View | Details | Raw Unified | Return to bug 389386
Collapse All | Expand All

(-)xorg-server-1.4.orig/configure.ac (+58 lines)
Lines 518-523 AC_ARG_ENABLE(xfree86-utils, AS_HELP Link Here
518
dnl DDXes.
518
dnl DDXes.
519
AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
519
AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
520
AC_ARG_ENABLE(dmx,    	      AS_HELP_STRING([--enable-dmx], [Build DMX server (default: no)]), [DMX=$enableval], [DMX=no])
520
AC_ARG_ENABLE(dmx,    	      AS_HELP_STRING([--enable-dmx], [Build DMX server (default: no)]), [DMX=$enableval], [DMX=no])
521
522
AC_ARG_ENABLE(xcliplist,      AS_HELP_STRING([--enable-xcliplist], [Build XClipList extension (default: auto)]), [XCLIPLIST=$enableval], [XCLIPLIST=auto])
523
AC_ARG_ENABLE(vnc,    	      AS_HELP_STRING([--enable-vnc], [Build Xvnc server (default: yes)]), [VNC=$enableval], [VNC=auto])
524
521
AC_ARG_ENABLE(xvfb,    	      AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes])
525
AC_ARG_ENABLE(xvfb,    	      AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes])
522
AC_ARG_ENABLE(xnest,   	      AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto])
526
AC_ARG_ENABLE(xnest,   	      AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto])
523
AC_ARG_ENABLE(xwin,    	      AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
527
AC_ARG_ENABLE(xwin,    	      AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
Lines 887-892 XI_INC='-I$(top_srcdir)/Xi' Link Here
887
891
888
AM_CONDITIONAL(XF86UTILS, test "x$XF86UTILS" = xyes)
892
AM_CONDITIONAL(XF86UTILS, test "x$XF86UTILS" = xyes)
889
893
894
if test "x$XCLIPLIST" = xauto; then
895
	if test "x$XORG" = xno; then
896
		XCLIPLIST=no
897
	else
898
		PKG_CHECK_MODULES([XCLIPLIST], [xcliplistproto xcliplist], [XCLIPLIST=yes], [XCLIPLIST=no])
899
	fi
900
fi
901
AM_CONDITIONAL(XCLIPLIST, [test "x$XCLIPLIST" = xyes])
902
if test "x$XCLIPLIST" = xyes; then
903
	AC_DEFINE(XCLIPLIST, 1, [Support XClipList extension])
904
	REQUIRED_MODULES="$REQUIRED_MODULES xcliplistproto"
905
	XCLIPLIST_LIB='$(top_builddir)/xcliplist/libxcliplist.la'
906
fi
907
890
AC_DEFINE(SHAPE, 1, [Support SHAPE extension])
908
AC_DEFINE(SHAPE, 1, [Support SHAPE extension])
891
909
892
AC_DEFINE(XKB, 1, [Build XKB])
910
AC_DEFINE(XKB, 1, [Build XKB])
Lines 1000-1005 MI_EXT_LIB='$(top_builddir)/mi/libmiext. Link Here
1000
MI_INC='-I$(top_srcdir)/mi'
1018
MI_INC='-I$(top_srcdir)/mi'
1001
FB_LIB='$(top_builddir)/fb/libfb.la'
1019
FB_LIB='$(top_builddir)/fb/libfb.la'
1002
FB_INC='-I$(top_srcdir)/fb'
1020
FB_INC='-I$(top_srcdir)/fb'
1021
MFB_LIB='$(top_builddir)/mfb/libmfb.la'
1022
MFB_INC='-I$(top_srcdir)/mfb'
1003
MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/shadow'
1023
MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/shadow'
1004
MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la'
1024
MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la'
1005
XPSTUBS_LIB='$(top_builddir)/dix/libxpstubs.la'
1025
XPSTUBS_LIB='$(top_builddir)/dix/libxpstubs.la'
Lines 1162-1167 AM_CONDITIONAL([DMX_BUILD_LNX], [test "x Link Here
1162
AM_CONDITIONAL([DMX_BUILD_USB], [test "x$DMX_BUILD_USB" = xyes])
1182
AM_CONDITIONAL([DMX_BUILD_USB], [test "x$DMX_BUILD_USB" = xyes])
1163
1183
1164
1184
1185
1186
dnl VNC DDX
1187
1188
AC_MSG_CHECKING([whether to build Xvnc DDX])
1189
PKG_CHECK_MODULES([VNCMODULES], [xmuu xext x11 xrender xfont xi vncproto xau $XDMCP_MODULES $PIXMAN], [have_vnc=yes], [have_vnc=no])
1190
if test "x$VNC" = xauto; then
1191
	VNC="$have_vnc"
1192
fi
1193
AC_MSG_RESULT([$VNC])
1194
AM_CONDITIONAL(VNC, [test "x$VNC" = xyes])
1195
1196
if test "x$VNC" = xyes; then
1197
	if test "x$have_vnc" = xno; then
1198
		AC_MSG_ERROR([Xvnc build explicitly requested, but required
1199
		              modules not found.])
1200
	fi
1201
	XVNC_CFLAGS="-DVNCSERVER -DHAVE_XVNC_CONFIG_H $PIXMAN_CFLAGS"
1202
	AC_SUBST([XVNC_CFLAGS])
1203
	VNC_INCLUDES="$XEXT_INC $RENDER_INC $XTRAP_INC $RECORD_INC"
1204
	XVNC_LIBS="$GLX_LIBS $MFB_LIB $FB_LIB $MI_LIB $XEXT_LIB $RENDER_LIB $XTRAP_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $OS_LIB $CWRAP_LIB"
1205
	AC_SUBST([XVNC_LIBS])
1206
1207
	if test "x$GLX" = xyes; then
1208
		PKG_CHECK_MODULES([GL], [glproto])
1209
	fi
1210
	PKG_CHECK_MODULES([XVNCCONFIG_DEP], [xaw7 xmu xt xpm x11])
1211
	AC_SUBST(XVNCCONFIG_DEP_CFLAGS)
1212
	AC_SUBST(XVNCCONFIG_DEP_LIBS)
1213
        $srcdir/hw/vnc/symlink-vnc.sh $srcdir/hw/vnc $srcdir/hw/xfree86/vnc
1214
        $srcdir/hw/vnc/symlink-vnc.sh $srcdir/hw/vnc $srcdir/hw/dmx/vnc
1215
fi
1216
1217
1218
1165
dnl Xvfb DDX
1219
dnl Xvfb DDX
1166
1220
1167
AC_MSG_CHECKING([whether to build Xvfb DDX])
1221
AC_MSG_CHECKING([whether to build Xvfb DDX])
Lines 2011-2016 Xext/Makefile Link Here
2011
Xi/Makefile
2065
Xi/Makefile
2012
xfixes/Makefile
2066
xfixes/Makefile
2013
exa/Makefile
2067
exa/Makefile
2068
xcliplist/Makefile
2014
hw/Makefile
2069
hw/Makefile
2015
hw/xfree86/Makefile
2070
hw/xfree86/Makefile
2016
hw/xfree86/common/Makefile
2071
hw/xfree86/common/Makefile
Lines 2048-2053 hw/xfree86/scanpci/Makefile Link Here
2048
hw/xfree86/shadowfb/Makefile
2103
hw/xfree86/shadowfb/Makefile
2049
hw/xfree86/vbe/Makefile
2104
hw/xfree86/vbe/Makefile
2050
hw/xfree86/vgahw/Makefile
2105
hw/xfree86/vgahw/Makefile
2106
hw/xfree86/vnc/Makefile
2051
hw/xfree86/x86emu/Makefile
2107
hw/xfree86/x86emu/Makefile
2052
hw/xfree86/xaa/Makefile
2108
hw/xfree86/xaa/Makefile
2053
hw/xfree86/xf1bpp/Makefile
2109
hw/xfree86/xf1bpp/Makefile
Lines 2068-2075 hw/dmx/doc/Makefile Link Here
2068
hw/dmx/examples/Makefile
2124
hw/dmx/examples/Makefile
2069
hw/dmx/input/Makefile
2125
hw/dmx/input/Makefile
2070
hw/dmx/glxProxy/Makefile
2126
hw/dmx/glxProxy/Makefile
2127
hw/dmx/vnc/Makefile
2071
hw/dmx/Makefile
2128
hw/dmx/Makefile
2072
hw/vfb/Makefile
2129
hw/vfb/Makefile
2130
hw/vnc/Makefile
2073
hw/xgl/Makefile
2131
hw/xgl/Makefile
2074
hw/xgl/egl/Makefile
2132
hw/xgl/egl/Makefile
2075
hw/xgl/egl/module/Makefile
2133
hw/xgl/egl/module/Makefile
(-)xorg-server-1.4.orig/hw/dmx/dmx-config.h (+3 lines)
Lines 72-77 Link Here
72
/* Enable the DMX extension */
72
/* Enable the DMX extension */
73
#define DMXEXT
73
#define DMXEXT
74
74
75
/* Enable VNC ability */
76
#define DMXVNC 1
77
75
/* Disable the extensions that are not currently supported */
78
/* Disable the extensions that are not currently supported */
76
#undef BEZIER
79
#undef BEZIER
77
#undef PEXEXT
80
#undef PEXEXT
(-)xorg-server-1.4.orig/hw/dmx/dmxinit.c (+18 lines)
Lines 77-82 extern void GlxSetVisualConfigs( Link Here
77
);
77
);
78
#endif /* GLXEXT */
78
#endif /* GLXEXT */
79
79
80
#ifdef DMXVNC
81
extern void VNCInitForDMX(void);
82
#endif
83
80
/* Global variables available to all Xserver/hw/dmx routines. */
84
/* Global variables available to all Xserver/hw/dmx routines. */
81
int             dmxNumScreens;
85
int             dmxNumScreens;
82
DMXScreenInfo  *dmxScreens;
86
DMXScreenInfo  *dmxScreens;
Lines 812-817 void InitOutput(ScreenInfo *pScreenInfo, Link Here
812
816
813
    dmxLog(dmxInfo, "Shadow framebuffer support %s\n",
817
    dmxLog(dmxInfo, "Shadow framebuffer support %s\n",
814
	   dmxShadowFB ? "enabled" : "disabled");
818
	   dmxShadowFB ? "enabled" : "disabled");
819
#ifdef DMXVNC
820
    VNCInitForDMX();
821
#endif
815
}
822
}
816
823
817
/* RATS: Assuming the fp string (which comes from the command-line argv
824
/* RATS: Assuming the fp string (which comes from the command-line argv
Lines 1045-1047 void ddxUseMsg(void) Link Here
1045
    ErrorF("        Ctrl-Alt-q    Quit (core devices only)\n");
1052
    ErrorF("        Ctrl-Alt-q    Quit (core devices only)\n");
1046
    ErrorF("        Ctrl-Alt-F*   Switch to VC (local only)\n");
1053
    ErrorF("        Ctrl-Alt-F*   Switch to VC (local only)\n");
1047
}
1054
}
1055
1056
#ifdef DDXTIME
1057
/** Return wall-clock time in milliseconds. */
1058
CARD32 GetTimeInMillis(void)
1059
{
1060
    struct timeval  tp;
1061
1062
    gettimeofday(&tp, 0);
1063
    return tp.tv_sec * 1000 + tp.tv_usec / 1000;
1064
}
1065
#endif
(-)xorg-server-1.4.orig/hw/dmx/dmxsync.c (+7 lines)
Lines 99-107 static void dmxSyncBlockHandler(pointer Link Here
99
    TimerForce(dmxSyncTimer);
99
    TimerForce(dmxSyncTimer);
100
}
100
}
101
101
102
#ifdef DMXVNC
103
extern void rfbWakeupHandlerDMX(void);
104
#endif
105
102
static void dmxSyncWakeupHandler(pointer blockData, int result,
106
static void dmxSyncWakeupHandler(pointer blockData, int result,
103
                                 pointer pReadMask)
107
                                 pointer pReadMask)
104
{
108
{
109
#ifdef DMXVNC
110
   rfbWakeupHandlerDMX();
111
#endif
105
}
112
}
106
113
107
/** Request the XSync() batching optimization with the specified \a
114
/** Request the XSync() batching optimization with the specified \a
(-)xorg-server-1.4.orig/hw/dmx/input/dmxcommon.c (-1 lines)
Lines 655-661 void dmxCommonRestoreState(pointer priva Link Here
655
            dmxLogInput(dmxInput, "Keyboard busy, waiting\n");
655
            dmxLogInput(dmxInput, "Keyboard busy, waiting\n");
656
        else
656
        else
657
            dmxLogInput(dmxInput, "Keyboard error, waiting\n");
657
            dmxLogInput(dmxInput, "Keyboard error, waiting\n");
658
659
                                /* Don't generate X11 protocol for a bit */
658
                                /* Don't generate X11 protocol for a bit */
660
        for (tmp = GetTimeInMillis(); GetTimeInMillis() - tmp < 250;) {
659
        for (tmp = GetTimeInMillis(); GetTimeInMillis() - tmp < 250;) {
661
            usleep(250);            /* This ends up sleeping only until
660
            usleep(250);            /* This ends up sleeping only until
(-)xorg-server-1.4.orig/hw/dmx/input/dmxinputinit.c (+11 lines)
Lines 393-398 static int dmxKeyboardOn(DeviceIntPtr pD Link Here
393
    DevicePtr pDev = &pDevice->public;
393
    DevicePtr pDev = &pDevice->public;
394
#endif
394
#endif
395
395
396
#ifdef DMXVNC
397
    vncSetKeyboardDevice(pDevice);
398
#endif
399
396
#ifdef XKB
400
#ifdef XKB
397
    if (noXkbExtension) {
401
    if (noXkbExtension) {
398
#endif
402
#endif
Lines 480-485 static int dmxDeviceOnOff(DeviceIntPtr p Link Here
480
            break;
484
            break;
481
        }
485
        }
482
        if (info.keyClass) {
486
        if (info.keyClass) {
487
#ifdef DMXVNC
488
            vncSetKeyboardDevice(pDevice);
489
#endif
490
483
#if 00 /*BP*/
491
#if 00 /*BP*/
484
            InitKeyClassDeviceStruct(pDevice, &info.keySyms, info.modMap);
492
            InitKeyClassDeviceStruct(pDevice, &info.keySyms, info.modMap);
485
#else
493
#else
Lines 534-539 static int dmxDeviceOnOff(DeviceIntPtr p Link Here
534
                                           info.maxres[i+1]);
542
                                           info.maxres[i+1]);
535
#endif
543
#endif
536
            }
544
            }
545
#ifdef DMXVNC
546
            vncSetPointerDevice(pDevice);
547
#endif
537
        }
548
        }
538
        if (info.focusClass)       InitFocusClassDeviceStruct(pDevice);
549
        if (info.focusClass)       InitFocusClassDeviceStruct(pDevice);
539
#ifdef XINPUT
550
#ifdef XINPUT
(-)xorg-server-1.4.orig/hw/dmx/input/dmxinputinit.h (+5 lines)
Lines 290-293 extern int dmxInputAttachConsol Link Here
290
extern int          dmxInputAttachBackend(int physicalScreen, int isCore,
290
extern int          dmxInputAttachBackend(int physicalScreen, int isCore,
291
                                          int *id);
291
                                          int *id);
292
292
293
#ifdef DMXVNC
294
extern void vncSetKeyboardDevice(DeviceIntPtr kbd);
295
extern void vncSetPointerDevice(DeviceIntPtr ptr);
296
#endif
297
293
#endif
298
#endif
(-)xorg-server-1.4.orig/hw/dmx/input/Makefile.am (+1 lines)
Lines 65-70 AM_CFLAGS = $(DIX_CFLAGS) \ Link Here
65
            -I$(top_srcdir)/hw/xfree86/common \
65
            -I$(top_srcdir)/hw/xfree86/common \
66
            $(GLX_INCS) \
66
            $(GLX_INCS) \
67
            -DHAVE_DMX_CONFIG_H \
67
            -DHAVE_DMX_CONFIG_H \
68
            -DDMXVNC=1 \
68
            $(GLX_DEFS) \
69
            $(GLX_DEFS) \
69
            @DMXMODULES_CFLAGS@
70
            @DMXMODULES_CFLAGS@
70
71
(-)xorg-server-1.4.orig/hw/dmx/Makefile.am (-2 / +4 lines)
Lines 1-6 Link Here
1
DIST_SUBDIRS = input config glxProxy examples doc
1
DIST_SUBDIRS = input vnc config glxProxy examples doc
2
2
3
SUBDIRS = input config examples
3
SUBDIRS = input vnc config examples
4
bin_PROGRAMS = Xdmx
4
bin_PROGRAMS = Xdmx
5
5
6
if XINERAMA
6
if XINERAMA
Lines 86-92 Xdmx_LDADD = $(XORG_CORE_LIBS) \ Link Here
86
             $(XDMX_LIBS) \
86
             $(XDMX_LIBS) \
87
             $(GLX_LIBS) \
87
             $(GLX_LIBS) \
88
             input/libdmxinput.a \
88
             input/libdmxinput.a \
89
             vnc/libdmxvnc.a \
89
             config/libdmxconfig.a \
90
             config/libdmxconfig.a \
91
             -ljpeg -lcrypt \
90
             @DMXMODULES_LIBS@
92
             @DMXMODULES_LIBS@
91
93
92
# Man page
94
# Man page
(-)xorg-server-1.4.orig/hw/dmx/vnc/Makefile.am (+43 lines)
Line 0 Link Here
1
noinst_LIBRARIES = libdmxvnc.a
2
3
SRCS = \
4
	auth.c \
5
	cmap.c \
6
	corre.c \
7
	cursor.c \
8
	cutpaste.c \
9
	d3des.c \
10
	dispcur.c \
11
	draw.c \
12
	hextile.c \
13
	httpd.c \
14
	kbdptr.c \
15
	loginauth.c \
16
	rdp.c \
17
	rfbkeyb.c \
18
	rfbmouse.c \
19
	rfbserver.c \
20
	rre.c \
21
	sockets.c \
22
	sprite.c \
23
	stats.c \
24
	tight.c \
25
	translate.c \
26
	vncauth.c \
27
	vncext.c \
28
	vncInit.c \
29
	xistubs.c \
30
	zlib.c
31
32
33
libdmxvnc_a_SOURCES = $(SRCS)
34
35
AM_CFLAGS = \
36
            -I$(top_srcdir)/hw/dmx \
37
            -I$(top_srcdir)/hw/xfree86/common \
38
            -DHAVE_DMX_CONFIG_H \
39
	    $(DIX_CFLAGS) \
40
            -DDMXVNC=1 \
41
            @DMXMODULES_CFLAGS@
42
43
###EXTRA_DIST = dmxdetach.c
(-)xorg-server-1.4.orig/hw/dmx/vnc/vncInit.c (+453 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2002 Alan Hourihane.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this software; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 *
19
 *  Author: Alan Hourihane <alanh@fairlite.demon.co.uk>
20
 */
21
22
#include "rfb.h"
23
24
#ifdef HAVE_DMX_CONFIG_H
25
#include "dmx-config.h"
26
#endif
27
28
#ifdef DMXVNC
29
#include "../dmx.h"
30
#include "../dmxcb.h"
31
#endif
32
33
#include <time.h>
34
#include "fb.h"
35
36
#include "dixstruct.h"
37
#include "compiler.h"
38
39
#include "mipointer.h"
40
#include "mibstore.h"
41
42
#include "globals.h"
43
#define DPMS_SERVER
44
#include <X11/extensions/dpms.h>
45
46
#include <netinet/in.h>
47
48
int vncScreenPrivateIndex = -1;
49
int rfbGCIndex = -1;
50
int inetdSock = -1;
51
Atom VNC_LAST_CLIENT_ID = 0;
52
Atom VNC_CONNECT = 0;
53
char *desktopName = "x11";
54
char rfbThisHost[256];
55
56
extern void VncExtensionInit(void);
57
58
extern void vncInitMouse(void);
59
extern void vncInitKeyb(void);
60
Bool VNCInit(ScreenPtr pScreen, DMXScreenInfo *dmxScreen);
61
62
#ifndef XFree86LOADER
63
static unsigned long VNCGeneration = 0;
64
#endif
65
static void rfbWakeupHandler (int i, pointer blockData, unsigned long err, pointer pReadmask);
66
67
/*
68
 * rfbLog prints a time-stamped message to the log file (stderr).
69
 */
70
71
void rfbLog(char *format, ...)
72
{
73
    va_list args;
74
    char buf[256];
75
    time_t clock;
76
77
    va_start(args, format);
78
79
    time(&clock);
80
    strftime(buf, 255, "%d/%m/%Y %H:%M:%S ", localtime(&clock));
81
    fprintf(stderr, buf);
82
83
    vfprintf(stderr, format, args);
84
    fflush(stderr);
85
86
    va_end(args);
87
}
88
89
void rfbLogPerror(char *str)
90
{
91
    rfbLog("");
92
    perror(str);
93
}
94
95
96
static ScreenPtr TheVNCScreen = NULL;
97
98
99
static void
100
nopGetImage(DrawablePtr pDrawable, int sx, int sy,
101
            int w, int h, unsigned int format,
102
            unsigned long planemask, char *pdstLine)
103
{
104
   ScreenPtr pScreen = pDrawable->pScreen;
105
106
   (*pScreen->GetImage)(pDrawable,sx,sy,w,h,format,planemask,pdstLine);
107
}
108
109
110
static void
111
SetupVNCScreen(void)
112
{
113
    vncScreenPtr pScreenPriv;
114
    VisualPtr v = NULL;
115
    int i;
116
117
    pScreenPriv = xalloc(sizeof(vncScreenRec));
118
    pScreenPriv->width = dmxGlobalWidth;
119
    pScreenPriv->height = dmxGlobalHeight;
120
    pScreenPriv->rfbAuthTries = 0;
121
    pScreenPriv->rfbAuthTooManyTries = FALSE;
122
    pScreenPriv->timer = NULL;
123
    pScreenPriv->udpPort = 0;
124
    pScreenPriv->rfbListenSock = -1;
125
    pScreenPriv->udpSock = -1;
126
    pScreenPriv->udpSockConnected = FALSE;
127
    pScreenPriv->httpListenSock = -1;
128
    pScreenPriv->httpSock = -1;
129
    pScreenPriv->maxFd = 0;
130
    pScreenPriv->rfbAuthPasswdFile = NULL;
131
    pScreenPriv->httpDir = NULL;
132
    pScreenPriv->rfbInstalledColormap = NULL;
133
    pScreenPriv->interface.s_addr = htonl (INADDR_ANY);
134
135
    pScreenPriv->rfbPort = 0;
136
    pScreenPriv->httpPort = 0;
137
    pScreenPriv->rfbAuthPasswdFile = NULL;
138
    pScreenPriv->httpDir = NULL;
139
    pScreenPriv->rfbAlwaysShared = FALSE;
140
    pScreenPriv->rfbNeverShared = FALSE;
141
    pScreenPriv->rfbUserAccept = FALSE;
142
    pScreenPriv->rfbViewOnly = FALSE;
143
    pScreenPriv->rfbDontDisconnect = FALSE;
144
    pScreenPriv->loginAuthEnabled = FALSE;
145
146
    /* Find the root window's visual.
147
     * XXX this might be the wrong info to use below.
148
     */
149
    for (i = 0; i < screenInfo.screens[0]->numVisuals; i++) {
150
        v = screenInfo.screens[0]->visuals + i;
151
        if (v->vid == screenInfo.screens[0]->rootVisual) {
152
            break;
153
        }
154
    }
155
156
    /* XXX is this the right depth and bpp? */
157
    /* With DMX, screenInfo.screens[0]->rootDepth is 24 and that doesn't
158
     * work in translate.c!  We're just using 32.
159
     */
160
    pScreenPriv->rfbServerFormat.bitsPerPixel = 32;
161
    pScreenPriv->rfbServerFormat.depth = 32;
162
    pScreenPriv->rfbServerFormat.bigEndian = 0;
163
    pScreenPriv->rfbServerFormat.trueColour = (v->class == TrueColor);
164
    if (pScreenPriv->rfbServerFormat.trueColour) {
165
	pScreenPriv->rfbServerFormat.redMax = v->redMask >> v->offsetRed;
166
	pScreenPriv->rfbServerFormat.greenMax = v->greenMask >> v->offsetGreen;
167
	pScreenPriv->rfbServerFormat.blueMax = v->blueMask >> v->offsetBlue;
168
	pScreenPriv->rfbServerFormat.redShift = v->offsetRed;
169
	pScreenPriv->rfbServerFormat.greenShift = v->offsetGreen;
170
	pScreenPriv->rfbServerFormat.blueShift = v->offsetBlue;
171
    } else {
172
	pScreenPriv->rfbServerFormat.redMax
173
	    = pScreenPriv->rfbServerFormat.greenMax 
174
	    = pScreenPriv->rfbServerFormat.blueMax = 0;
175
	pScreenPriv->rfbServerFormat.redShift
176
	    = pScreenPriv->rfbServerFormat.greenShift 
177
	    = pScreenPriv->rfbServerFormat.blueShift = 0;
178
    }
179
180
    /* Allocate/init TheVNCScreen object */
181
    vncScreenPrivateIndex = 0;
182
183
    TheVNCScreen = (ScreenPtr) Xcalloc(1, sizeof(struct _Screen));
184
    TheVNCScreen->devPrivates = (DevUnion *) Xcalloc(1, sizeof(DevUnion));
185
    TheVNCScreen->devPrivates[vncScreenPrivateIndex].ptr = pScreenPriv;
186
    TheVNCScreen->GetImage = nopGetImage;
187
188
    rfbInitSockets(TheVNCScreen);
189
    if (inetdSock == -1)
190
       httpInitSockets(TheVNCScreen);
191
}
192
193
194
/*
195
 * Called by DMX's InitOutput()
196
 * Will be called for each X server generation.
197
 */
198
void
199
VNCInitForDMX(void)
200
{
201
    rfbLog("DMXVNC: Initializing VNC for DMX\n");
202
    ErrorF("DMXVNC: Initializing VNC for DMX\n");
203
204
    if (TheVNCScreen) {
205
        rfbLog("DMXVNC: New server generation\n");
206
    }
207
    else {
208
        rfbLog("DMXVNC: Set up VNC screen\n");
209
        SetupVNCScreen();
210
    }
211
212
    /* Reset the input device pointers.  They'll get set later.
213
     * This allows successful server regeneration.
214
    */
215
    vncSetKeyboardDevice(NULL);
216
    vncSetPointerDevice(NULL);
217
}
218
219
220
Bool
221
VNCInit(ScreenPtr pScreen, DMXScreenInfo *pScrn)
222
{
223
    VisualPtr visual;
224
    vncScreenPtr pScreenPriv;
225
#if 0
226
    char *interface_str = NULL;
227
#endif
228
#ifdef RENDER
229
    PictureScreenPtr	ps;
230
#endif
231
232
#ifndef XFree86LOADER
233
    if (VNCGeneration != serverGeneration) {
234
	VNCGeneration = serverGeneration;
235
	if ( ((vncScreenPrivateIndex = AllocateScreenPrivateIndex()) < 0) ||
236
	    ((rfbGCIndex = AllocateGCPrivateIndex()) < 0) )
237
		return FALSE;
238
    }
239
#endif
240
241
    if (!AllocateGCPrivate(pScreen, rfbGCIndex, sizeof(rfbGCRec))) {
242
	ErrorF("VNCInit(): failed to allocate GCIndex\n");
243
	return FALSE;
244
    }
245
246
    if (!(pScreenPriv = xalloc(sizeof(vncScreenRec))))
247
	return FALSE;
248
249
    pScreen->devPrivates[vncScreenPrivateIndex].ptr = (pointer)pScreenPriv;
250
251
    pScreenPriv->rfbAuthTries = 0;
252
    pScreenPriv->rfbAuthTooManyTries = FALSE;
253
    pScreenPriv->timer = NULL;
254
    pScreenPriv->udpPort = 0;
255
    pScreenPriv->rfbListenSock = -1;
256
    pScreenPriv->udpSock = -1;
257
    pScreenPriv->udpSockConnected = FALSE;
258
    pScreenPriv->httpListenSock = -1;
259
    pScreenPriv->httpSock = -1;
260
    pScreenPriv->maxFd = 0;
261
    pScreenPriv->rfbAuthPasswdFile = NULL;
262
    pScreenPriv->httpDir = NULL;
263
    pScreenPriv->rfbInstalledColormap = NULL;
264
    pScreenPriv->interface.s_addr = htonl (INADDR_ANY);
265
266
    pScreenPriv->rfbPort = 0;
267
    pScreenPriv->httpPort = 0;
268
    pScreenPriv->rfbAuthPasswdFile = NULL;
269
    pScreenPriv->httpDir = NULL;
270
    pScreenPriv->rfbAlwaysShared = FALSE;
271
    pScreenPriv->rfbNeverShared = FALSE;
272
    pScreenPriv->rfbUserAccept = FALSE;
273
    pScreenPriv->rfbViewOnly = FALSE;
274
    pScreenPriv->rfbDontDisconnect = FALSE;
275
    pScreenPriv->loginAuthEnabled = FALSE;
276
277
#if 0
278
    if (xf86ReturnOptValBool(options, OPTION_LOCALHOST, FALSE))
279
	pScreenPriv->interface.s_addr = htonl (INADDR_LOOPBACK);
280
281
    interface_str = xf86GetOptValString(options, OPTION_INTERFACE);
282
283
    if (interface_str && pScreenPriv->interface.s_addr == htonl(INADDR_ANY)) {
284
	Bool failed = FALSE;
285
	struct in_addr got;
286
	unsigned long octet;
287
	char *p = interface_str, *end;
288
	int q;
289
290
	for (q = 0; q < 4; q++) {
291
	    octet = strtoul (p, &end, 10);
292
293
	    if (p == end || octet > 255)
294
		failed = TRUE;
295
296
	    if ((q < 3 && *end != '.') ||
297
	        (q == 3 && *end != '\0'))
298
		failed = TRUE;
299
300
	    got.s_addr = (got.s_addr << 8) | octet;
301
	    p = end + 1;
302
	}
303
304
	if (!failed)
305
	    pScreenPriv->interface.s_addr = htonl (got.s_addr);
306
	else
307
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VNC interface option malformed, not using.\n");
308
    }
309
#endif
310
311
    if (!VNC_LAST_CLIENT_ID)
312
    	VNC_LAST_CLIENT_ID = MakeAtom("VNC_LAST_CLIENT_ID",
313
				  strlen("VNC_LAST_CLIENT_ID"), TRUE);
314
    if (!VNC_CONNECT)
315
    	VNC_CONNECT = MakeAtom("VNC_CONNECT", strlen("VNC_CONNECT"), TRUE);
316
317
    rfbInitSockets(pScreen);
318
    if (inetdSock == -1)
319
    	httpInitSockets(pScreen);
320
   
321
#ifdef CORBA
322
    initialiseCORBA(argc, argv, desktopName);
323
#endif
324
325
    pScreenPriv->width = pScrn->scrnWidth;
326
    pScreenPriv->height = pScrn->scrnHeight;
327
    pScreenPriv->depth = pScrn->beDepth;
328
    pScreenPriv->paddedWidthInBytes = PixmapBytePad(pScrn->scrnWidth, pScrn->beDepth);
329
    pScreenPriv->bitsPerPixel = rfbBitsPerPixel(pScrn->beDepth);
330
    pScreenPriv->pfbMemory = NULL;
331
    pScreenPriv->oldpfbMemory = NULL;
332
333
    pScreenPriv->cursorIsDrawn = TRUE;
334
    pScreenPriv->dontSendFramebufferUpdate = FALSE;
335
336
    pScreenPriv->CloseScreen = pScreen->CloseScreen;
337
    pScreenPriv->CreateGC = pScreen->CreateGC;
338
    pScreenPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
339
    pScreenPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
340
    pScreenPriv->CopyWindow = pScreen->CopyWindow;
341
    pScreenPriv->ClearToBackground = pScreen->ClearToBackground;
342
    pScreenPriv->RestoreAreas = pScreen->RestoreAreas;
343
    pScreenPriv->WakeupHandler = pScreen->WakeupHandler;
344
    pScreenPriv->InstallColormap = pScreen->InstallColormap;
345
    pScreenPriv->UninstallColormap = pScreen->UninstallColormap;
346
    pScreenPriv->ListInstalledColormaps = pScreen->ListInstalledColormaps;
347
    pScreenPriv->StoreColors = pScreen->StoreColors;
348
#ifdef CHROMIUM
349
    pScreenPriv->RealizeWindow = pScreen->RealizeWindow;
350
    pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
351
    pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
352
    pScreenPriv->PositionWindow = pScreen->PositionWindow;
353
    pScreenPriv->ResizeWindow = pScreen->ResizeWindow;
354
    pScreenPriv->ClipNotify = pScreen->ClipNotify;
355
#endif
356
#ifdef RENDER
357
    ps = GetPictureScreenIfSet(pScreen);
358
    if (ps)
359
    	pScreenPriv->Composite = ps->Composite;
360
#endif
361
    pScreen->CloseScreen = rfbCloseScreen;
362
    pScreen->CreateGC = rfbCreateGC;
363
    pScreen->PaintWindowBackground = rfbPaintWindowBackground;
364
    pScreen->PaintWindowBorder = rfbPaintWindowBorder;
365
    pScreen->CopyWindow = rfbCopyWindow;
366
    pScreen->ClearToBackground = rfbClearToBackground;
367
    pScreen->RestoreAreas = rfbRestoreAreas;
368
    pScreen->WakeupHandler = rfbWakeupHandler;
369
    pScreen->InstallColormap = rfbInstallColormap;
370
    pScreen->UninstallColormap = rfbUninstallColormap;
371
    pScreen->ListInstalledColormaps = rfbListInstalledColormaps;
372
    pScreen->StoreColors = rfbStoreColors;
373
374
#ifdef CHROMIUM
375
    pScreen->RealizeWindow = rfbRealizeWindow;
376
    pScreen->UnrealizeWindow = rfbUnrealizeWindow;
377
    pScreen->DestroyWindow = rfbDestroyWindow;
378
    pScreen->PositionWindow = rfbPositionWindow;
379
    pScreen->ResizeWindow = rfbResizeWindow;
380
    pScreen->ClipNotify = rfbClipNotify;
381
#endif
382
#ifdef RENDER
383
    if (ps)
384
    	ps->Composite = rfbComposite;
385
#endif
386
387
    for (visual = pScreen->visuals; visual->vid != pScreen->rootVisual; visual++)
388
	;
389
390
    if (!visual) {
391
	ErrorF("rfbScreenInit: couldn't find root visual\n");
392
	return FALSE;
393
    }
394
395
    pScreenPriv->rfbServerFormat.bitsPerPixel = pScrn->beBPP;
396
    pScreenPriv->rfbServerFormat.depth = pScrn->beDepth;
397
    pScreenPriv->rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest);
398
    pScreenPriv->rfbServerFormat.trueColour = (visual->class == TrueColor);
399
    if (pScreenPriv->rfbServerFormat.trueColour) {
400
	pScreenPriv->rfbServerFormat.redMax = visual->redMask >> visual->offsetRed;
401
	pScreenPriv->rfbServerFormat.greenMax = visual->greenMask >> visual->offsetGreen;
402
	pScreenPriv->rfbServerFormat.blueMax = visual->blueMask >> visual->offsetBlue;
403
	pScreenPriv->rfbServerFormat.redShift = visual->offsetRed;
404
	pScreenPriv->rfbServerFormat.greenShift = visual->offsetGreen;
405
	pScreenPriv->rfbServerFormat.blueShift = visual->offsetBlue;
406
    } else {
407
	pScreenPriv->rfbServerFormat.redMax
408
	    = pScreenPriv->rfbServerFormat.greenMax 
409
	    = pScreenPriv->rfbServerFormat.blueMax = 0;
410
	pScreenPriv->rfbServerFormat.redShift
411
	    = pScreenPriv->rfbServerFormat.greenShift 
412
	    = pScreenPriv->rfbServerFormat.blueShift = 0;
413
    }
414
415
    return TRUE;
416
}
417
418
static void
419
rfbWakeupHandler (
420
    int 	i,	
421
    pointer     blockData,
422
    unsigned long err,
423
    pointer     pReadmask
424
){
425
    ScreenPtr      pScreen = screenInfo.screens[i];
426
    vncScreenPtr   pScreenPriv = VNCPTR(pScreen);
427
    /*DMXScreenInfo *pScrn = &dmxScreens[pScreen->myNum];*/
428
429
    rfbRootPropertyChange(pScreen); /* Check clipboard */
430
431
    rfbCheckFds(pScreen);
432
    httpCheckFds(pScreen);
433
#ifdef CORBA
434
    corbaCheckFds();
435
#endif
436
437
    pScreen->WakeupHandler = pScreenPriv->WakeupHandler;
438
    (*pScreen->WakeupHandler) (i, blockData, err, pReadmask);
439
    pScreen->WakeupHandler = rfbWakeupHandler;
440
}
441
442
443
/**
444
 * The rfb wake-up handler used when we're compiled into the DMX server.
445
 */
446
void
447
rfbWakeupHandlerDMX(void)
448
{
449
    ScreenPtr      pScreen = TheVNCScreen;
450
    rfbRootPropertyChange(pScreen); /* Check clipboard */
451
    rfbCheckFds(pScreen);
452
    httpCheckFds(pScreen);
453
}
(-)xorg-server-1.4.orig/hw/dmx/vnc/vncint.h (+153 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2002 Alan Hourihane.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this software; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 *
19
 *  Author: Alan Hourihane <alanh@fairlite.demon.co.uk>
20
 */
21
22
#ifndef _VNCINT_H_
23
#define _VNCINT_H_
24
25
#include <netinet/in.h>
26
27
extern int vncScreenPrivateIndex;
28
29
#define VNCPTR(pScreen)\
30
   (vncScreenPtr)((pScreen)->devPrivates[vncScreenPrivateIndex].ptr)
31
32
typedef struct {
33
    int			rfbPort;
34
    int			rdpPort;
35
    int			udpPort;
36
    int			rfbListenSock;
37
    int			rdpListenSock;
38
    int			udpSock;
39
    int			httpPort;
40
    int			httpListenSock;
41
    int			httpSock;
42
    char *		httpDir;
43
    char		buf[HTTP_BUF_SIZE];
44
    Bool		udpSockConnected;
45
    char *		rfbAuthPasswdFile;
46
    size_t		buf_filled;
47
    int			maxFd;
48
    fd_set		allFds;
49
    unsigned char *	oldpfbMemory;
50
    Bool		rfbAlwaysShared;
51
    Bool		rfbNeverShared;
52
    Bool		rfbDontDisconnect;
53
    Bool		rfbUserAccept;
54
    Bool		rfbViewOnly;
55
    unsigned char *	pfbMemory;
56
    int 		paddedWidthInBytes;
57
    ColormapPtr 	rfbInstalledColormap;
58
    ColormapPtr		savedColormap;
59
    rfbPixelFormat	rfbServerFormat;
60
    Bool		rfbAuthTooManyTries;
61
    int			rfbAuthTries;
62
    Bool		loginAuthEnabled;
63
    struct in_addr	interface;
64
    OsTimerPtr 		timer;
65
    unsigned char 	updateBuf[UPDATE_BUF_SIZE];
66
    int 		ublen;
67
    int 		width;
68
    int 		height;
69
    int 		depth;
70
    int 		bitsPerPixel;
71
72
    /* The following two members are used to minimise the amount of unnecessary
73
       drawing caused by cursor movement.  Whenever any drawing affects the
74
       part of the screen where the cursor is, the cursor is removed first and
75
       then the drawing is done (this is what the sprite routines test for).
76
       Afterwards, however, we do not replace the cursor, even when the cursor
77
       is logically being moved across the screen.  We only draw the cursor
78
       again just as we are about to send the client a framebuffer update.
79
80
       We need to be careful when removing and drawing the cursor because of
81
       their relationship with the normal drawing routines.  The drawing
82
       routines can invoke the cursor routines, but also the cursor routines
83
       themselves end up invoking drawing routines.
84
85
       Removing the cursor (rfbSpriteRemoveCursor) is eventually achieved by
86
       doing a CopyArea from a pixmap to the screen, where the pixmap contains
87
       the saved contents of the screen under the cursor.  Before doing this,
88
       however, we set cursorIsDrawn to FALSE.  Then, when CopyArea is called,
89
       it sees that cursorIsDrawn is FALSE and so doesn't feel the need to
90
       (recursively!) remove the cursor before doing it.
91
92
       Putting up the cursor (rfbSpriteRestoreCursor) involves a call to
93
       PushPixels.  While this is happening, cursorIsDrawn must be FALSE so
94
       that PushPixels doesn't think it has to remove the cursor first.
95
       Obviously cursorIsDrawn is set to TRUE afterwards.
96
97
       Another problem we face is that drawing routines sometimes cause a
98
       framebuffer update to be sent to the RFB client.  When the RFB client is
99
       already waiting for a framebuffer update and some drawing to the
100
       framebuffer then happens, the drawing routine sees that the client is
101
       ready, so it calls rfbSendFramebufferUpdate.  If the cursor is not drawn
102
       at this stage, it must be put up, and so rfbSpriteRestoreCursor is
103
       called.  However, if the original drawing routine was actually called
104
       from within rfbSpriteRestoreCursor or rfbSpriteRemoveCursor we don't
105
       want this to happen.  So both the cursor routines set
106
       dontSendFramebufferUpdate to TRUE, and all the drawing routines check
107
       this before calling rfbSendFramebufferUpdate. */
108
109
    Bool cursorIsDrawn;		    /* TRUE if the cursor is currently drawn */
110
    Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the
111
				       cursor */
112
113
    /* wrapped screen functions */
114
115
    CloseScreenProcPtr			CloseScreen;
116
    CreateGCProcPtr			CreateGC;
117
    PaintWindowBackgroundProcPtr	PaintWindowBackground;
118
    PaintWindowBorderProcPtr		PaintWindowBorder;
119
    CopyWindowProcPtr			CopyWindow;
120
    ClearToBackgroundProcPtr		ClearToBackground;
121
    RestoreAreasProcPtr			RestoreAreas;
122
    ScreenWakeupHandlerProcPtr 		WakeupHandler;
123
    InstallColormapProcPtr		InstallColormap;
124
    UninstallColormapProcPtr		UninstallColormap;
125
    ListInstalledColormapsProcPtr 	ListInstalledColormaps;
126
    StoreColorsProcPtr			StoreColors;
127
    DisplayCursorProcPtr		DisplayCursor;
128
    CursorPtr				pCurs;
129
    Bool				(*UseHWCursor)(ScreenPtr, CursorPtr);
130
    Bool				(*UseHWCursorARGB)(ScreenPtr, CursorPtr);
131
    Bool				*SWCursor;
132
#ifdef CHROMIUM
133
    RealizeWindowProcPtr		RealizeWindow;
134
    UnrealizeWindowProcPtr		UnrealizeWindow;
135
    DestroyWindowProcPtr		DestroyWindow;
136
    ResizeWindowProcPtr			ResizeWindow;
137
    PositionWindowProcPtr		PositionWindow;
138
    ClipNotifyProcPtr			ClipNotify;
139
#endif
140
#ifdef RENDER
141
    CompositeProcPtr			Composite;
142
#endif
143
144
} vncScreenRec, *vncScreenPtr;
145
146
extern Bool vncUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
147
extern Bool vncUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
148
149
extern void
150
rfbSendChromiumStart(unsigned int ipaddress, unsigned int port);
151
152
#endif /* _VNCINT_H_ */
153
(-)xorg-server-1.4.orig/hw/Makefile.am (-1 / +7 lines)
Lines 38-43 if XPRINT Link Here
38
XPRINT_SUBDIRS = xprint
38
XPRINT_SUBDIRS = xprint
39
endif
39
endif
40
40
41
if VNC
42
VNC_SUBDIRS = vnc
43
endif
44
45
# need to add darwin support here
41
if BUILD_DARWIN
46
if BUILD_DARWIN
42
DARWIN_SUBDIRS = darwin
47
DARWIN_SUBDIRS = darwin
43
endif
48
endif
Lines 50-59 SUBDIRS = \ Link Here
50
	$(XVFB_SUBDIRS)		\
55
	$(XVFB_SUBDIRS)		\
51
	$(XNEST_SUBDIRS)	\
56
	$(XNEST_SUBDIRS)	\
52
	$(DMX_SUBDIRS)          \
57
	$(DMX_SUBDIRS)          \
58
	$(VNC_SUBDIRS)          \
53
        $(KDRIVE_SUBDIRS)	\
59
        $(KDRIVE_SUBDIRS)	\
54
	$(XPRINT_SUBDIRS)
60
	$(XPRINT_SUBDIRS)
55
61
56
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin darwin kdrive xgl xprint
62
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin darwin kdrive xgl xprint vnc
57
63
58
relink:
64
relink:
59
	for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink ; done
65
	for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink ; done
(-)xorg-server-1.4.orig/hw/vnc/auth.c (+566 lines)
Line 0 Link Here
1
/*
2
 * auth.c - deal with authentication.
3
 *
4
 * This file implements authentication when setting up an RFB connection.
5
 *
6
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
7
 */
8
9
/*
10
 *  Copyright (C) 2003-2004 Constantin Kaplinsky.  All Rights Reserved.
11
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
12
 *
13
 *  This is free software; you can redistribute it and/or modify
14
 *  it under the terms of the GNU General Public License as published by
15
 *  the Free Software Foundation; either version 2 of the License, or
16
 *  (at your option) any later version.
17
 *
18
 *  This software is distributed in the hope that it will be useful,
19
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 *  GNU General Public License for more details.
22
 *
23
 *  You should have received a copy of the GNU General Public License
24
 *  along with this software; if not, write to the Free Software
25
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
26
 *  USA.
27
 */
28
#ifdef HAVE_DIX_CONFIG_H
29
#include <dix-config.h>
30
#endif
31
32
#include "rfb.h"
33
#include "windowstr.h"
34
35
static void rfbSendSecurityType(rfbClientPtr cl, int securityType);
36
static void rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType);
37
static void rfbSendTunnelingCaps(rfbClientPtr cl);
38
static void rfbSendAuthCaps(rfbClientPtr cl);
39
static void rfbVncAuthSendChallenge(rfbClientPtr cl);
40
41
/*
42
 * rfbAuthNewClient is called right after negotiating the protocol
43
 * version. Depending on the protocol version, we send either a code
44
 * for authentication scheme to be used (protocol 3.3), or a list of
45
 * possible "security types" (protocol 3.7).
46
 */
47
48
void
49
rfbAuthNewClient(cl)
50
    rfbClientPtr cl;
51
{
52
    VNCSCREENPTR(cl->pScreen);
53
    int securityType = rfbSecTypeInvalid;
54
 
55
    if ((!pVNC->rfbAuthPasswdFile && !pVNC->loginAuthEnabled) || cl->reverseConnection) {
56
	securityType = rfbSecTypeNone;
57
    } else {
58
	if (rfbAuthIsBlocked(cl)) {
59
	    rfbLog("Too many authentication failures - client rejected\n");
60
	    rfbClientConnFailed(cl, "Too many authentication failures");
61
	    return;
62
	}
63
	if (pVNC->rfbAuthPasswdFile)
64
	    securityType = rfbSecTypeVncAuth;
65
    }
66
 
67
    if (cl->protocol_minor_ver < 7) {
68
	/* Make sure we use only RFB 3.3 compatible security types. */
69
	if (securityType == rfbSecTypeInvalid) {
70
	    rfbLog("VNC authentication disabled - RFB 3.3 client rejected\n");
71
	    rfbClientConnFailed(cl, "Your viewer cannot handle required "
72
				"authentication methods");
73
	    return;
74
	}
75
	rfbSendSecurityType(cl, securityType);
76
    } else {
77
	/* Here it's ok when securityType is set to rfbSecTypeInvalid. */
78
	rfbSendSecurityTypeList(cl, securityType);
79
    }
80
}
81
 
82
83
/*
84
 * Tell the client what security type will be used (protocol 3.3).
85
 */
86
87
static void
88
rfbSendSecurityType(cl, securityType)
89
    rfbClientPtr cl;
90
    int securityType;
91
{
92
    CARD32 value32;
93
94
    /* Send the value. */
95
    value32 = Swap32IfLE(securityType);
96
    if (WriteExact(cl->sock, (char *)&value32, 4) < 0) {
97
	rfbLogPerror("rfbSendSecurityType: write");
98
	rfbCloseSock(cl->pScreen, cl->sock);
99
	return;
100
    }
101
102
    /* Decide what to do next. */
103
    switch (securityType) {
104
    case rfbSecTypeNone:
105
	/* Dispatch client input to rfbProcessClientInitMessage. */
106
	cl->state = RFB_INITIALISATION;
107
	break;
108
    case rfbSecTypeVncAuth:
109
	/* Begin the standard VNC authentication procedure. */
110
	rfbVncAuthSendChallenge(cl);
111
	break;
112
    default:
113
	/* Impossible case (hopefully). */
114
	rfbLogPerror("rfbSendSecurityType: assertion failed");
115
	rfbCloseSock(cl->pScreen, cl->sock);
116
    }
117
}
118
119
120
/*
121
 * Advertise our supported security types (protocol 3.7). The list
122
 * will include one standard security type (if primaryType is not set
123
 * to rfbSecTypeInvalid), and then one more value telling the client
124
 * that we support TightVNC protocol extensions. Thus, currently,
125
 * there will be either 1 or 2 items in the list.
126
 */
127
128
static void
129
rfbSendSecurityTypeList(cl, primaryType)
130
    rfbClientPtr cl;
131
    int primaryType;
132
{
133
    int count = 1;
134
135
    /* Fill in the list of security types in the client structure. */
136
    if (primaryType != rfbSecTypeInvalid) {
137
	cl->securityTypes[count++] = (CARD8)primaryType;
138
    }
139
    cl->securityTypes[count] = (CARD8)rfbSecTypeTight;
140
    cl->securityTypes[0] = (CARD8)count++;
141
142
    /* Send the list. */
143
    if (WriteExact(cl->sock, (char *)cl->securityTypes, count) < 0) {
144
	rfbLogPerror("rfbSendSecurityTypeList: write");
145
	rfbCloseSock(cl->pScreen, cl->sock);
146
	return;
147
    }
148
149
    /* Dispatch client input to rfbProcessClientSecurityType. */
150
    cl->state = RFB_SECURITY_TYPE;
151
}
152
153
154
/*
155
 * Read the security type chosen by the client (protocol 3.7).
156
 */
157
158
void
159
rfbProcessClientSecurityType(cl)
160
    rfbClientPtr cl;
161
{
162
    int n, count, i;
163
    CARD8 chosenType;
164
165
    /* Read the security type. */
166
    n = ReadExact(cl->sock, (char *)&chosenType, 1);
167
    if (n <= 0) {
168
	if (n == 0)
169
	    rfbLog("rfbProcessClientSecurityType: client gone\n");
170
	else
171
	    rfbLogPerror("rfbProcessClientSecurityType: read");
172
	rfbCloseSock(cl->pScreen, cl->sock);
173
	return;
174
    }
175
176
    /* Make sure it was present in the list sent by the server. */
177
    count = (int)cl->securityTypes[0];
178
    for (i = 1; i <= count; i++) {
179
	if (chosenType == cl->securityTypes[i])
180
	    break;
181
    }
182
    if (i > count) {
183
	rfbLog("rfbProcessClientSecurityType: "
184
	       "wrong security type requested\n");
185
	rfbCloseSock(cl->pScreen, cl->sock);
186
	return;
187
    }
188
189
    /* Now go to the proper authentication procedure. */
190
    switch (chosenType) {
191
    case rfbSecTypeNone:
192
	/* Dispatch client input to rfbProcessClientInitMessage. */
193
	cl->state = RFB_INITIALISATION;
194
	break;
195
    case rfbSecTypeVncAuth:
196
	/* Begin the standard VNC authentication procedure. */
197
	rfbVncAuthSendChallenge(cl);
198
	break;
199
    case rfbSecTypeTight:
200
	/* We are lucky: the viewer supports TightVNC extensions. */
201
	rfbLog("Enabling TightVNC protocol extensions\n");
202
	/* Switch to the protocol 3.7t. */
203
	cl->protocol_tightvnc = TRUE;
204
	/* Advertise our tunneling capabilities. */
205
	rfbSendTunnelingCaps(cl);
206
	break;
207
    default:
208
	/* Impossible case (hopefully). */
209
	rfbLog("rfbProcessClientSecurityType: "
210
	       "unknown authentication scheme\n");
211
	rfbCloseSock(cl->pScreen, cl->sock);
212
    }
213
}
214
215
216
/*
217
 * Send the list of our tunneling capabilities (protocol 3.7t).
218
 */
219
220
static void
221
rfbSendTunnelingCaps(cl)
222
    rfbClientPtr cl;
223
{
224
    rfbTunnelingCapsMsg caps;
225
    CARD32 nTypes = 0;		/* we don't support tunneling yet */
226
227
    caps.nTunnelTypes = Swap32IfLE(nTypes);
228
    if (WriteExact(cl->sock, (char *)&caps, sz_rfbTunnelingCapsMsg) < 0) {
229
	rfbLogPerror("rfbSendTunnelingCaps: write");
230
	rfbCloseSock(cl->pScreen, cl->sock);
231
	return;
232
    }
233
234
    if (nTypes) {
235
	/* Dispatch client input to rfbProcessClientTunnelingType(). */
236
	cl->state = RFB_TUNNELING_TYPE;
237
    } else {
238
	rfbSendAuthCaps(cl);
239
    }
240
}
241
242
243
/*
244
 * Read tunneling type requested by the client (protocol 3.7t).
245
 * NOTE: Currently, we don't support tunneling, and this function
246
 *       can never be called.
247
 */
248
249
void
250
rfbProcessClientTunnelingType(cl)
251
    rfbClientPtr cl;
252
{
253
    /* If we were called, then something's really wrong. */
254
    rfbLog("rfbProcessClientTunnelingType: not implemented\n");
255
    rfbCloseSock(cl->pScreen, cl->sock);
256
    return;
257
}
258
259
260
/*
261
 * Send the list of our authentication capabilities to the client
262
 * (protocol 3.7t).
263
 */
264
265
static void
266
rfbSendAuthCaps(cl)
267
    rfbClientPtr cl;
268
{
269
    VNCSCREENPTR(cl->pScreen);
270
    Bool authRequired;
271
    rfbAuthenticationCapsMsg caps;
272
    rfbCapabilityInfo caplist[MAX_AUTH_CAPS];
273
    int count = 0;
274
275
    authRequired = ((pVNC->rfbAuthPasswdFile != NULL || pVNC->loginAuthEnabled) &&
276
		    !cl->reverseConnection);
277
278
    if (authRequired) {
279
	if (pVNC->loginAuthEnabled) {
280
	    SetCapInfo(&caplist[count], rfbAuthUnixLogin, rfbTightVncVendor);
281
	    cl->authCaps[count++] = rfbAuthUnixLogin;
282
	}
283
	if (pVNC->rfbAuthPasswdFile != NULL) {
284
	    SetCapInfo(&caplist[count], rfbAuthVNC, rfbStandardVendor);
285
	    cl->authCaps[count++] = rfbAuthVNC;
286
	}
287
	if (count == 0) {
288
	    /* Should never happen. */
289
	    rfbLog("rfbSendAuthCaps: assertion failed\n");
290
     	    rfbCloseSock(cl->pScreen, cl->sock);
291
 	    return;
292
 	}
293
    }
294
 
295
    cl->nAuthCaps = count;
296
    caps.nAuthTypes = Swap32IfLE((CARD32)count);
297
    if (WriteExact(cl->sock, (char *)&caps, sz_rfbAuthenticationCapsMsg) < 0) {
298
	rfbLogPerror("rfbSendAuthCaps: write");
299
     	rfbCloseSock(cl->pScreen, cl->sock);
300
	return;
301
    }
302
 
303
    if (count) {
304
	if (WriteExact(cl->sock, (char *)&caplist[0],
305
		       count * sz_rfbCapabilityInfo) < 0) {
306
	    rfbLogPerror("rfbSendAuthCaps: write");
307
	    rfbCloseSock(cl->pScreen, cl->sock);
308
	    return;
309
	}
310
	/* Dispatch client input to rfbProcessClientAuthType. */
311
	cl->state = RFB_AUTH_TYPE;
312
     } else {
313
	/* Dispatch client input to rfbProcessClientInitMessage. */
314
	cl->state = RFB_INITIALISATION;
315
    }
316
}
317
 
318
319
/*
320
 * Read client's preferred authentication type (protocol 3.7t).
321
 */
322
323
void
324
rfbProcessClientAuthType(cl)
325
    rfbClientPtr cl;
326
{
327
    CARD32 auth_type;
328
    int n, i;
329
330
    /* Read authentication type selected by the client. */
331
    n = ReadExact(cl->sock, (char *)&auth_type, sizeof(auth_type));
332
    if (n <= 0) {
333
	if (n == 0)
334
	    rfbLog("rfbProcessClientAuthType: client gone\n");
335
	else
336
	    rfbLogPerror("rfbProcessClientAuthType: read");
337
	rfbCloseSock(cl->pScreen, cl->sock);
338
	return;
339
    }
340
    auth_type = Swap32IfLE(auth_type);
341
342
    /* Make sure it was present in the list sent by the server. */
343
    for (i = 0; i < cl->nAuthCaps; i++) {
344
	if (auth_type == cl->authCaps[i])
345
	    break;
346
    }
347
    if (i >= cl->nAuthCaps) {
348
	rfbLog("rfbProcessClientAuthType: "
349
	       "wrong authentication type requested\n");
350
     	rfbCloseSock(cl->pScreen, cl->sock);
351
	return;
352
    }
353
354
    switch (auth_type) {
355
    case rfbAuthNone:
356
	/* Dispatch client input to rfbProcessClientInitMessage. */
357
 	cl->state = RFB_INITIALISATION;
358
	break;
359
    case rfbAuthVNC:
360
	rfbVncAuthSendChallenge(cl);
361
	break;
362
    case rfbAuthUnixLogin:
363
	/* FIXME: Do (cl->state = RFB_LOGIN_AUTH) instead? */
364
	rfbLoginAuthProcessClientMessage(cl);
365
	break;
366
    default:
367
	rfbLog("rfbProcessClientAuthType: unknown authentication scheme\n");
368
     	rfbCloseSock(cl->pScreen, cl->sock);
369
     }
370
}
371
 
372
373
/*
374
 * Send the authentication challenge.
375
 */
376
377
static void
378
rfbVncAuthSendChallenge(cl)
379
    rfbClientPtr cl;
380
{
381
    vncRandomBytes(cl->authChallenge);
382
    if (WriteExact(cl->sock, (char *)cl->authChallenge, CHALLENGESIZE) < 0) {
383
	rfbLogPerror("rfbVncAuthSendChallenge: write");
384
     	rfbCloseSock(cl->pScreen, cl->sock);
385
 	return;
386
     }
387
388
    /* Dispatch client input to rfbVncAuthProcessResponse. */
389
    cl->state = RFB_AUTHENTICATION;
390
}
391
392
/*
393
 * rfbVncAuthProcessResponse is called when the client sends its
394
 * authentication response.
395
 */
396
397
void
398
rfbVncAuthProcessResponse(cl)
399
    rfbClientPtr cl;
400
{
401
    VNCSCREENPTR(cl->pScreen);
402
    char passwdFullControl[9];
403
    char passwdViewOnly[9];
404
    int numPasswords;
405
    Bool ok;
406
    int n;
407
    CARD8 encryptedChallenge1[CHALLENGESIZE];
408
    CARD8 encryptedChallenge2[CHALLENGESIZE];
409
    CARD8 response[CHALLENGESIZE];
410
    CARD32 authResult;
411
412
    n = ReadExact(cl->sock, (char *)response, CHALLENGESIZE);
413
    if (n <= 0) {
414
	if (n != 0)
415
	    rfbLogPerror("rfbVncAuthProcessResponse: read");
416
     	rfbCloseSock(cl->pScreen, cl->sock);
417
	return;
418
    }
419
420
    numPasswords = vncDecryptPasswdFromFile2(pVNC->rfbAuthPasswdFile,
421
					     passwdFullControl,
422
					     passwdViewOnly);
423
    if (numPasswords == 0) {
424
	rfbLog("rfbVncAuthProcessResponse: could not get password from %s\n",
425
	       pVNC->rfbAuthPasswdFile);
426
427
	authResult = Swap32IfLE(rfbVncAuthFailed);
428
429
	if (WriteExact(cl->sock, (char *)&authResult, 4) < 0) {
430
	    rfbLogPerror("rfbVncAuthProcessResponse: write");
431
	}
432
	rfbCloseSock(cl->pScreen, cl->sock);
433
	return;
434
    }
435
436
    memcpy(encryptedChallenge1, cl->authChallenge, CHALLENGESIZE);
437
    vncEncryptBytes(encryptedChallenge1, passwdFullControl);
438
    memcpy(encryptedChallenge2, cl->authChallenge, CHALLENGESIZE);
439
    vncEncryptBytes(encryptedChallenge2,
440
		    (numPasswords == 2) ? passwdViewOnly : passwdFullControl);
441
442
    /* Lose the passwords from memory */
443
    memset(passwdFullControl, 0, 9);
444
    memset(passwdViewOnly, 0, 9);
445
446
    ok = FALSE;
447
    if (memcmp(encryptedChallenge1, response, CHALLENGESIZE) == 0) {
448
	rfbLog("Full-control authentication passed by %s\n", cl->host);
449
	ok = TRUE;
450
	cl->viewOnly = FALSE;
451
    } else if (memcmp(encryptedChallenge2, response, CHALLENGESIZE) == 0) {
452
	rfbLog("View-only authentication passed by %s\n", cl->host);
453
	ok = TRUE;
454
	cl->viewOnly = TRUE;
455
    }
456
457
    if (!ok) {
458
	rfbLog("rfbVncAuthProcessResponse: authentication failed from %s\n",
459
	       cl->host);
460
461
	if (rfbAuthConsiderBlocking(cl)) {
462
	    authResult = Swap32IfLE(rfbVncAuthTooMany);
463
	} else {
464
	    authResult = Swap32IfLE(rfbVncAuthFailed);
465
	}
466
467
	if (WriteExact(cl->sock, (char *)&authResult, 4) < 0) {
468
	    rfbLogPerror("rfbVncAuthProcessResponse: write");
469
	}
470
	rfbCloseSock(cl->pScreen, cl->sock);
471
	return;
472
    }
473
474
    rfbAuthUnblock(cl);
475
476
    authResult = Swap32IfLE(rfbVncAuthOK);
477
478
    if (WriteExact(cl->sock, (char *)&authResult, 4) < 0) {
479
	rfbLogPerror("rfbVncAuthProcessResponse: write");
480
	rfbCloseSock(cl->pScreen, cl->sock);
481
	return;
482
    }
483
484
    /* Dispatch client input to rfbProcessClientInitMessage(). */
485
    cl->state = RFB_INITIALISATION;
486
}
487
488
489
/*
490
 * Functions to prevent too many successive authentication failures.
491
 * FIXME: This should be performed separately per each client IP.
492
 */
493
494
/* Maximum authentication failures before blocking connections */
495
#define MAX_AUTH_TRIES 5
496
497
/* Delay in ms, doubles for each failure over MAX_AUTH_TRIES */
498
#define AUTH_TOO_MANY_BASE_DELAY 10 * 1000
499
500
/*
501
 * This function should not be called directly, it is called by
502
 * setting a timer in rfbAuthConsiderBlocking().
503
 */
504
505
static CARD32
506
rfbAuthReenable(OsTimerPtr timer, CARD32 now, pointer arg)
507
{
508
    rfbClientPtr cl = (rfbClientPtr) arg;
509
    VNCSCREENPTR(cl->pScreen);
510
    (void)cl;
511
    pVNC->rfbAuthTooManyTries = FALSE;
512
    return 0;
513
}
514
515
/*
516
 * This function should be called after each authentication failure.
517
 * The return value will be true if there was too many failures.
518
 */
519
520
Bool
521
rfbAuthConsiderBlocking(rfbClientPtr cl)
522
{
523
    VNCSCREENPTR(cl->pScreen);
524
    int i;
525
526
    pVNC->rfbAuthTries++;
527
528
    if (pVNC->rfbAuthTries >= MAX_AUTH_TRIES) {
529
	CARD32 delay = AUTH_TOO_MANY_BASE_DELAY;
530
	for (i = MAX_AUTH_TRIES; i < pVNC->rfbAuthTries; i++)
531
	    delay *= 2;
532
	pVNC->timer = TimerSet(pVNC->timer, 0, delay, rfbAuthReenable, cl);
533
	pVNC->rfbAuthTooManyTries = TRUE;
534
	return TRUE;
535
    }
536
537
    return FALSE;
538
}
539
540
/*
541
 * This function should be called after successful authentication.
542
 * It resets the counter of authentication failures. Note that it's
543
 * not necessary to clear the rfbAuthTooManyTries flag as it will be
544
 * reset by the timer function.
545
 */
546
547
void
548
rfbAuthUnblock(rfbClientPtr cl)
549
{
550
    VNCSCREENPTR(cl->pScreen);
551
    pVNC->rfbAuthTries = 0;
552
}
553
554
/*
555
 * This function should be called before authentication process.
556
 * The return value will be true if there was too many authentication
557
 * failures, and the server should not allow another try.
558
 */
559
560
Bool
561
rfbAuthIsBlocked(rfbClientPtr cl)
562
{
563
    VNCSCREENPTR(cl->pScreen);
564
    return pVNC->rfbAuthTooManyTries;
565
}
566
(-)xorg-server-1.4.orig/hw/vnc/cmap.c (+166 lines)
Line 0 Link Here
1
/*
2
 * cmap.c
3
 *
4
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
5
 */
6
7
/*
8
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
9
 *
10
 *  This is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  This software is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this software; if not, write to the Free Software
22
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
23
 *  USA.
24
 */
25
26
/*
27
28
Copyright (c) 1993  X Consortium
29
30
Permission is hereby granted, free of charge, to any person obtaining
31
a copy of this software and associated documentation files (the
32
"Software"), to deal in the Software without restriction, including
33
without limitation the rights to use, copy, modify, merge, publish,
34
distribute, sublicense, and/or sell copies of the Software, and to
35
permit persons to whom the Software is furnished to do so, subject to
36
the following conditions:
37
38
The above copyright notice and this permission notice shall be included
39
in all copies or substantial portions of the Software.
40
41
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
42
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
43
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
44
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
45
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
46
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
47
OTHER DEALINGS IN THE SOFTWARE.
48
49
Except as contained in this notice, the name of the X Consortium shall
50
not be used in advertising or otherwise to promote the sale, use or
51
other dealings in this Software without prior written authorization
52
from the X Consortium.
53
54
*/
55
#ifdef HAVE_DIX_CONFIG_H
56
#include <dix-config.h>
57
#endif
58
59
#include "rfb.h"
60
61
int
62
rfbListInstalledColormaps(pScreen, pmaps)
63
    ScreenPtr	pScreen;
64
    Colormap	*pmaps;
65
{
66
    VNCSCREENPTR(pScreen);
67
    /* By the time we are processing requests, we can guarantee that there
68
     * is always a colormap installed */
69
    if (pVNC->rfbInstalledColormap)
70
    	*pmaps = pVNC->rfbInstalledColormap->mid;
71
72
#if XFREE86VNC
73
    pScreen->ListInstalledColormaps = pVNC->ListInstalledColormaps;
74
    (*pScreen->ListInstalledColormaps)(pScreen, pmaps);
75
    pScreen->ListInstalledColormaps = rfbListInstalledColormaps;
76
#endif
77
78
    return (1);
79
}
80
81
82
void
83
rfbInstallColormap(pmap)
84
    ColormapPtr	pmap;
85
{
86
    VNCSCREENPTR(pmap->pScreen);
87
88
    if (pmap != pVNC->rfbInstalledColormap) {
89
90
	if(pVNC->rfbInstalledColormap != (ColormapPtr)None)
91
	    WalkTree(pmap->pScreen, TellLostMap,
92
				 (char *)&pVNC->rfbInstalledColormap->mid);
93
	/* Install pmap */
94
	pVNC->rfbInstalledColormap = pmap;
95
	WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
96
97
	rfbSetClientColourMaps(0, 0);
98
    }
99
#if XFREE86VNC
100
    pmap->pScreen->InstallColormap = pVNC->InstallColormap;
101
    (*pmap->pScreen->InstallColormap)(pmap);
102
    pmap->pScreen->InstallColormap = rfbInstallColormap;
103
#endif
104
}
105
106
void
107
rfbUninstallColormap(pmap)
108
    ColormapPtr	pmap;
109
{
110
    VNCSCREENPTR(pmap->pScreen);
111
112
    if(pmap == pVNC->rfbInstalledColormap)
113
    {
114
	if (pmap->mid != pmap->pScreen->defColormap)
115
	{
116
	    pVNC->rfbInstalledColormap = 
117
			(ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
118
						   RT_COLORMAP);
119
	    (*pmap->pScreen->InstallColormap)(pVNC->rfbInstalledColormap);
120
	}
121
    }
122
#if XFREE86VNC
123
    pmap->pScreen->UninstallColormap = pVNC->UninstallColormap;
124
    (*pmap->pScreen->UninstallColormap)(pmap);
125
    pmap->pScreen->UninstallColormap = rfbUninstallColormap;
126
#endif
127
}
128
129
130
/*
131
 * rfbStoreColors.  We have a set of pixels but they may be in any order.
132
 * If some of them happen to be in continuous ascending order then we can
133
 * group them together into a single call to rfbSetClientColourMaps.
134
 */
135
136
void
137
rfbStoreColors(pmap, ndef, pdefs)
138
    ColormapPtr pmap;
139
    int         ndef;
140
    xColorItem  *pdefs;
141
{
142
    VNCSCREENPTR(pmap->pScreen);
143
    int i;
144
    int first = -1;
145
    int n = 0;
146
147
    if (pmap == pVNC->rfbInstalledColormap) {
148
	for (i = 0; i < ndef; i++) {
149
	    if ((first != -1) && (first + n == pdefs[i].pixel)) {
150
		n++;
151
	    } else {
152
		if (first != -1) {
153
		    rfbSetClientColourMaps(first, n);
154
		}
155
		first = pdefs[i].pixel;
156
		n = 1;
157
	    }
158
	}
159
	rfbSetClientColourMaps(first, n);
160
    }
161
#if XFREE86VNC
162
    pmap->pScreen->StoreColors = pVNC->StoreColors;
163
    (*pmap->pScreen->StoreColors)(pmap, ndef, pdefs);
164
    pmap->pScreen->StoreColors = rfbStoreColors;
165
#endif
166
}
(-)xorg-server-1.4.orig/hw/vnc/corre.c (+353 lines)
Line 0 Link Here
1
/*
2
 * corre.c
3
 *
4
 * Routines to implement Compact Rise-and-Run-length Encoding (CoRRE).  This
5
 * code is based on krw's original javatel rfbserver.
6
 *
7
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
8
 */
9
10
/*
11
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
12
 *
13
 *  This is free software; you can redistribute it and/or modify
14
 *  it under the terms of the GNU General Public License as published by
15
 *  the Free Software Foundation; either version 2 of the License, or
16
 *  (at your option) any later version.
17
 *
18
 *  This software is distributed in the hope that it will be useful,
19
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 *  GNU General Public License for more details.
22
 *
23
 *  You should have received a copy of the GNU General Public License
24
 *  along with this software; if not, write to the Free Software
25
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
26
 *  USA.
27
 */
28
#ifdef HAVE_DIX_CONFIG_H
29
#include <dix-config.h>
30
#endif
31
32
#include <stdio.h>
33
#include "rfb.h"
34
35
/*
36
 * rreBeforeBuf contains pixel data in the client's format.
37
 * rreAfterBuf contains the RRE encoded version.  If the RRE encoded version is
38
 * larger than the raw data or if it exceeds rreAfterBufSize then
39
 * raw encoding is used instead.
40
 */
41
42
static int rreBeforeBufSize = 0;
43
static unsigned char *rreBeforeBuf = NULL;
44
45
static int rreAfterBufSize = 0;
46
static unsigned char *rreAfterBuf = NULL;
47
static int rreAfterBufLen;
48
49
static int subrectEncode8(CARD8 *data, int w, int h);
50
static int subrectEncode16(CARD16 *data, int w, int h);
51
static int subrectEncode32(CARD32 *data, int w, int h);
52
static CARD32 getBgColour(char *data, int size, int bpp);
53
static Bool rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, int x, int y,
54
					  int w, int h);
55
56
57
/*
58
 * rfbSendRectEncodingCoRRE - send an arbitrary size rectangle using CoRRE
59
 * encoding.
60
 */
61
62
Bool
63
rfbSendRectEncodingCoRRE(cl, x, y, w, h)
64
    rfbClientPtr cl;
65
    int x, y, w, h;
66
{
67
    if (h > cl->correMaxHeight) {
68
	return (rfbSendRectEncodingCoRRE(cl, x, y, w, cl->correMaxHeight) &&
69
		rfbSendRectEncodingCoRRE(cl, x, y + cl->correMaxHeight,
70
					 w, h - cl->correMaxHeight));
71
    }
72
73
    if (w > cl->correMaxWidth) {
74
	return (rfbSendRectEncodingCoRRE(cl, x, y, cl->correMaxWidth, h) &&
75
		rfbSendRectEncodingCoRRE(cl, x + cl->correMaxWidth, y,
76
					 w - cl->correMaxWidth, h));
77
    }
78
79
    return rfbSendSmallRectEncodingCoRRE(cl, x, y, w, h);
80
}
81
82
83
84
/*
85
 * rfbSendSmallRectEncodingCoRRE - send a small (guaranteed < 256x256)
86
 * rectangle using CoRRE encoding.
87
 */
88
89
static Bool
90
rfbSendSmallRectEncodingCoRRE(cl, x, y, w, h)
91
    rfbClientPtr cl;
92
    int x, y, w, h;
93
{
94
    VNCSCREENPTR(cl->pScreen);
95
    rfbFramebufferUpdateRectHeader rect;
96
    rfbRREHeader hdr;
97
    int nSubrects;
98
    int i;
99
    int maxRawSize = (pVNC->width * pVNC->height
100
		      * (cl->format.bitsPerPixel / 8));
101
102
    if (rreBeforeBufSize < maxRawSize) {
103
	rreBeforeBufSize = maxRawSize;
104
	if (rreBeforeBuf == NULL)
105
	    rreBeforeBuf = (unsigned char *)xalloc(rreBeforeBufSize);
106
	else
107
	    rreBeforeBuf = (unsigned char *)xrealloc(rreBeforeBuf, rreBeforeBufSize);
108
    }
109
110
    if (rreAfterBufSize < maxRawSize) {
111
	rreAfterBufSize = maxRawSize;
112
	if (rreAfterBuf == NULL)
113
	    rreAfterBuf = (unsigned char *)xalloc(rreAfterBufSize);
114
	else
115
	    rreAfterBuf = (unsigned char *)xrealloc(rreAfterBuf, rreAfterBufSize);
116
    }
117
118
    (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, 
119
		       &pVNC->rfbServerFormat,
120
		       &cl->format, rreBeforeBuf,
121
		       pVNC->paddedWidthInBytes, w, h, x, y);
122
123
    switch (cl->format.bitsPerPixel) {
124
    case 8:
125
	nSubrects = subrectEncode8((CARD8 *)rreBeforeBuf, w, h);
126
	break;
127
    case 16:
128
	nSubrects = subrectEncode16((CARD16 *)rreBeforeBuf, w, h);
129
	break;
130
    case 32:
131
	nSubrects = subrectEncode32((CARD32 *)rreBeforeBuf, w, h);
132
	break;
133
    default:
134
	rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel);
135
	exit(1);
136
    }
137
	
138
    if (nSubrects < 0) {
139
140
	/* RRE encoding was too large, use raw */
141
142
	return rfbSendRectEncodingRaw(cl, x, y, w, h);
143
    }
144
145
    cl->rfbRectanglesSent[rfbEncodingCoRRE]++;
146
    cl->rfbBytesSent[rfbEncodingCoRRE] += (sz_rfbFramebufferUpdateRectHeader
147
					   + sz_rfbRREHeader + rreAfterBufLen);
148
149
    if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader
150
	> UPDATE_BUF_SIZE)
151
    {
152
	if (!rfbSendUpdateBuf(cl))
153
	    return FALSE;
154
    }
155
156
    rect.r.x = Swap16IfLE(x);
157
    rect.r.y = Swap16IfLE(y);
158
    rect.r.w = Swap16IfLE(w);
159
    rect.r.h = Swap16IfLE(h);
160
    rect.encoding = Swap32IfLE(rfbEncodingCoRRE);
161
162
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,
163
	   sz_rfbFramebufferUpdateRectHeader);
164
    pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
165
166
    hdr.nSubrects = Swap32IfLE(nSubrects);
167
168
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&hdr, sz_rfbRREHeader);
169
    pVNC->ublen += sz_rfbRREHeader;
170
171
    for (i = 0; i < rreAfterBufLen;) {
172
173
	int bytesToCopy = UPDATE_BUF_SIZE - pVNC->ublen;
174
175
	if (i + bytesToCopy > rreAfterBufLen) {
176
	    bytesToCopy = rreAfterBufLen - i;
177
	}
178
179
	memcpy(&pVNC->updateBuf[pVNC->ublen], &rreAfterBuf[i], bytesToCopy);
180
181
	pVNC->ublen += bytesToCopy;
182
	i += bytesToCopy;
183
184
	if (pVNC->ublen == UPDATE_BUF_SIZE) {
185
	    if (!rfbSendUpdateBuf(cl))
186
		return FALSE;
187
	}
188
    }
189
190
    return TRUE;
191
}
192
193
194
195
/*
196
 * subrectEncode() encodes the given multicoloured rectangle as a background 
197
 * colour overwritten by single-coloured rectangles.  It returns the number 
198
 * of subrectangles in the encoded buffer, or -1 if subrect encoding won't
199
 * fit in the buffer.  It puts the encoded rectangles in rreAfterBuf.  The
200
 * single-colour rectangle partition is not optimal, but does find the biggest
201
 * horizontal or vertical rectangle top-left anchored to each consecutive 
202
 * coordinate position.
203
 *
204
 * The coding scheme is simply [<bgcolour><subrect><subrect>...] where each 
205
 * <subrect> is [<colour><x><y><w><h>].
206
 */
207
208
#define DEFINE_SUBRECT_ENCODE(bpp)					      \
209
static int								      \
210
subrectEncode##bpp(data,w,h)						      \
211
    CARD##bpp *data;							      \
212
    int w;								      \
213
    int h;								      \
214
{									      \
215
    CARD##bpp cl;							      \
216
    rfbCoRRERectangle subrect;						      \
217
    int x,y;								      \
218
    int i,j;								      \
219
    int hx=0,hy,vx=0,vy;						      \
220
    int hyflag;								      \
221
    CARD##bpp *seg;							      \
222
    CARD##bpp *line;							      \
223
    int hw,hh,vw,vh;							      \
224
    int thex,they,thew,theh;						      \
225
    int numsubs = 0;							      \
226
    int newLen;								      \
227
    CARD##bpp bg = (CARD##bpp)getBgColour((char*)data,w*h,bpp);		      \
228
									      \
229
    *((CARD##bpp*)rreAfterBuf) = bg;					      \
230
									      \
231
    rreAfterBufLen = (bpp/8);						      \
232
									      \
233
    for (y=0; y<h; y++) {						      \
234
      line = data+(y*w);						      \
235
      for (x=0; x<w; x++) {						      \
236
        if (line[x] != bg) {						      \
237
          cl = line[x];							      \
238
          hy = y-1;							      \
239
          hyflag = 1;							      \
240
          for (j=y; j<h; j++) {						      \
241
            seg = data+(j*w);						      \
242
            if (seg[x] != cl) {break;}					      \
243
            i = x;							      \
244
            while ((seg[i] == cl) && (i < w)) i += 1;			      \
245
            i -= 1;							      \
246
            if (j == y) vx = hx = i;					      \
247
            if (i < vx) vx = i;						      \
248
            if ((hyflag > 0) && (i >= hx)) {hy += 1;} else {hyflag = 0;}      \
249
          }								      \
250
          vy = j-1;							      \
251
									      \
252
          /*  We now have two possible subrects: (x,y,hx,hy) and (x,y,vx,vy)  \
253
           *  We'll choose the bigger of the two.			      \
254
           */								      \
255
          hw = hx-x+1;							      \
256
          hh = hy-y+1;							      \
257
          vw = vx-x+1;							      \
258
          vh = vy-y+1;							      \
259
									      \
260
          thex = x;							      \
261
          they = y;							      \
262
									      \
263
          if ((hw*hh) > (vw*vh)) {					      \
264
            thew = hw;							      \
265
            theh = hh;							      \
266
          } else {							      \
267
            thew = vw;							      \
268
            theh = vh;							      \
269
          }								      \
270
									      \
271
          subrect.x = thex;						      \
272
          subrect.y = they;						      \
273
          subrect.w = thew;						      \
274
          subrect.h = theh;						      \
275
									      \
276
	  newLen = rreAfterBufLen + (bpp/8) + sz_rfbCoRRERectangle;	      \
277
          if ((newLen > (w * h * (bpp/8))) || (newLen > rreAfterBufSize))     \
278
	    return -1;							      \
279
									      \
280
	  numsubs += 1;							      \
281
	  *((CARD##bpp*)(rreAfterBuf + rreAfterBufLen)) = cl;		      \
282
	  rreAfterBufLen += (bpp/8);					      \
283
	  memcpy(&rreAfterBuf[rreAfterBufLen],&subrect,sz_rfbCoRRERectangle); \
284
	  rreAfterBufLen += sz_rfbCoRRERectangle;			      \
285
									      \
286
          /*								      \
287
           * Now mark the subrect as done.				      \
288
           */								      \
289
          for (j=they; j < (they+theh); j++) {				      \
290
            for (i=thex; i < (thex+thew); i++) {			      \
291
              data[j*w+i] = bg;						      \
292
            }								      \
293
          }								      \
294
        }								      \
295
      }									      \
296
    }									      \
297
									      \
298
    return numsubs;							      \
299
}
300
301
DEFINE_SUBRECT_ENCODE(8)
302
DEFINE_SUBRECT_ENCODE(16)
303
DEFINE_SUBRECT_ENCODE(32)
304
305
306
/*
307
 * getBgColour() gets the most prevalent colour in a byte array.
308
 */
309
static CARD32
310
getBgColour(data,size,bpp)
311
    char *data;
312
    int size;
313
    int bpp;
314
{
315
    
316
#define NUMCLRS 256
317
  
318
  static int counts[NUMCLRS];
319
  int i,j,k;
320
321
  int maxcount = 0;
322
  CARD8 maxclr = 0;
323
324
  if (bpp != 8) {
325
    if (bpp == 16) {
326
      return ((CARD16 *)data)[0];
327
    } else if (bpp == 32) {
328
      return ((CARD32 *)data)[0];
329
    } else {
330
      rfbLog("getBgColour: bpp %d?\n",bpp);
331
      exit(1);
332
    }
333
  }
334
335
  for (i=0; i<NUMCLRS; i++) {
336
    counts[i] = 0;
337
  }
338
339
  for (j=0; j<size; j++) {
340
    k = (int)(((CARD8 *)data)[j]);
341
    if (k >= NUMCLRS) {
342
      rfbLog("getBgColour: unusual colour = %d\n", k);
343
      exit(1);
344
    }
345
    counts[k] += 1;
346
    if (counts[k] > maxcount) {
347
      maxcount = counts[k];
348
      maxclr = ((CARD8 *)data)[j];
349
    }
350
  }
351
  
352
  return maxclr;
353
}
(-)xorg-server-1.4.orig/hw/vnc/cursor.c (+407 lines)
Line 0 Link Here
1
/*
2
 * cursor.c - support for cursor shape updates.
3
 *
4
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
5
 */
6
7
/*
8
 *  Copyright (C) 2000, 2001 Const Kaplinsky.  All Rights Reserved.
9
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
10
 *
11
 *  This is free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  This software is distributed in the hope that it will be useful,
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *  GNU General Public License for more details.
20
 *
21
 *  You should have received a copy of the GNU General Public License
22
 *  along with this software; if not, write to the Free Software
23
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
24
 *  USA.
25
 */
26
#ifdef HAVE_DIX_CONFIG_H
27
#include <dix-config.h>
28
#endif
29
30
#include <stdio.h>
31
#include "rfb.h"
32
#include "mipointer.h"
33
#include "sprite.h"
34
#include "cursorstr.h"
35
#include "servermd.h"
36
37
38
/* Copied from Xvnc/lib/font/util/utilbitmap.c */
39
static unsigned char _reverse_byte[0x100] = {
40
	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
41
	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
42
	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
43
	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
44
	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
45
	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
46
	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
47
	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
48
	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
49
	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
50
	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
51
	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
52
	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
53
	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
54
	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
55
	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
56
	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
57
	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
58
	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
59
	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
60
	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
61
	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
62
	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
63
	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
64
	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
65
	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
66
	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
67
	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
68
	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
69
	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
70
	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
71
	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
72
};
73
74
75
static int EncodeRichCursorData8 (unsigned char *buf, rfbPixelFormat *fmt,
76
				  CursorPtr pCursor);
77
static int EncodeRichCursorData16 (ScreenPtr pScreen,
78
				   unsigned char *buf, rfbPixelFormat *fmt,
79
				   CursorPtr pCursor);
80
static int EncodeRichCursorData32 (ScreenPtr pScreen,
81
				   unsigned char *buf, rfbPixelFormat *fmt,
82
				   CursorPtr pCursor);
83
84
85
/*
86
 * Send cursor shape either in X-style format or in client pixel format.
87
 */
88
89
Bool
90
rfbSendCursorShape(cl, pScreen)
91
    rfbClientPtr cl;
92
    ScreenPtr pScreen;
93
{
94
    VNCSCREENPTR(pScreen);
95
    CursorPtr pCursor;
96
    rfbFramebufferUpdateRectHeader rect;
97
    rfbXCursorColors colors;
98
    int saved_ublen;
99
    int bitmapRowBytes, paddedRowBytes, maskBytes, dataBytes;
100
    int i, j;
101
    CARD8 *bitmapData;
102
    CARD8 bitmapByte;
103
104
    if (cl->useRichCursorEncoding) {
105
	rect.encoding = Swap32IfLE(rfbEncodingRichCursor);
106
    } else {
107
	rect.encoding = Swap32IfLE(rfbEncodingXCursor);
108
    }
109
110
#if XFREE86VNC
111
    pCursor = pVNC->pCurs;
112
#else
113
    pCursor = rfbSpriteGetCursorPtr(pScreen);
114
#endif
115
116
    /* If there is no cursor, send update with empty cursor data. */
117
118
    if ( pCursor != NULL &&
119
	 pCursor->bits->width == 1 &&
120
	 pCursor->bits->height == 1 &&
121
	 pCursor->bits->mask[0] == 0 ) {
122
	pCursor = NULL;
123
    }
124
125
    if (pCursor == NULL) {
126
	if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE ) {
127
	    if (!rfbSendUpdateBuf(cl))
128
		return FALSE;
129
	}
130
	rect.r.x = rect.r.y = 0;
131
	rect.r.w = rect.r.h = 0;
132
	memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,
133
	       sz_rfbFramebufferUpdateRectHeader);
134
	pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
135
136
	cl->rfbCursorShapeBytesSent += sz_rfbFramebufferUpdateRectHeader;
137
	cl->rfbCursorShapeUpdatesSent++;
138
139
	return TRUE;
140
    }
141
142
    /* Calculate data sizes. */
143
144
    bitmapRowBytes = (pCursor->bits->width + 7) / 8;
145
    paddedRowBytes = PixmapBytePad(pCursor->bits->width, 1);
146
    maskBytes = bitmapRowBytes * pCursor->bits->height;
147
    dataBytes = (cl->useRichCursorEncoding) ?
148
	(pCursor->bits->width * pCursor->bits->height *
149
	 (cl->format.bitsPerPixel / 8)) : maskBytes;
150
151
    /* Send buffer contents if needed. */
152
153
    if ( pVNC->ublen + sz_rfbFramebufferUpdateRectHeader +
154
	 sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) {
155
	if (!rfbSendUpdateBuf(cl))
156
	    return FALSE;
157
    }
158
159
    if ( pVNC->ublen + sz_rfbFramebufferUpdateRectHeader +
160
	 sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) {
161
	return FALSE;		/* FIXME. */
162
    }
163
164
    saved_ublen = pVNC->ublen;
165
166
    /* Prepare rectangle header. */
167
168
    rect.r.x = Swap16IfLE(pCursor->bits->xhot);
169
    rect.r.y = Swap16IfLE(pCursor->bits->yhot);
170
    rect.r.w = Swap16IfLE(pCursor->bits->width);
171
    rect.r.h = Swap16IfLE(pCursor->bits->height);
172
173
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader);
174
    pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
175
176
    /* Prepare actual cursor data (depends on encoding used). */
177
178
    if (!cl->useRichCursorEncoding) {
179
	/* XCursor encoding. */
180
	colors.foreRed   = (char)(pCursor->foreRed   >> 8);
181
	colors.foreGreen = (char)(pCursor->foreGreen >> 8);
182
	colors.foreBlue  = (char)(pCursor->foreBlue  >> 8);
183
	colors.backRed   = (char)(pCursor->backRed   >> 8);
184
	colors.backGreen = (char)(pCursor->backGreen >> 8);
185
	colors.backBlue  = (char)(pCursor->backBlue  >> 8);
186
187
	memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&colors, sz_rfbXCursorColors);
188
	pVNC->ublen += sz_rfbXCursorColors;
189
190
	bitmapData = (CARD8 *)pCursor->bits->source;
191
192
	for (i = 0; i < pCursor->bits->height; i++) {
193
	    for (j = 0; j < bitmapRowBytes; j++) {
194
		bitmapByte = bitmapData[i * paddedRowBytes + j];
195
		if (screenInfo.bitmapBitOrder == LSBFirst) {
196
		    bitmapByte = _reverse_byte[bitmapByte];
197
		}
198
		pVNC->updateBuf[pVNC->ublen++] = (char)bitmapByte;
199
	    }
200
	}
201
    } else {
202
	/* RichCursor encoding. */
203
	switch (cl->format.bitsPerPixel) {
204
	case 8:
205
	    pVNC->ublen += EncodeRichCursorData8(&pVNC->updateBuf[pVNC->ublen],
206
					   &cl->format, pCursor);
207
	    break;
208
	case 16:
209
	    pVNC->ublen += EncodeRichCursorData16(pScreen, &pVNC->updateBuf[pVNC->ublen],
210
					    &cl->format, pCursor);
211
	    break;
212
	case 32:
213
	    pVNC->ublen += EncodeRichCursorData32(pScreen, &pVNC->updateBuf[pVNC->ublen],
214
					    &cl->format, pCursor);
215
	    break;
216
	default:
217
	    return FALSE;
218
	}
219
    }
220
221
    /* Prepare transparency mask. */
222
223
    bitmapData = (CARD8 *)pCursor->bits->mask;
224
225
    for (i = 0; i < pCursor->bits->height; i++) {
226
	for (j = 0; j < bitmapRowBytes; j++) {
227
	    bitmapByte = bitmapData[i * paddedRowBytes + j];
228
	    if (screenInfo.bitmapBitOrder == LSBFirst) {
229
		bitmapByte = _reverse_byte[bitmapByte];
230
	    }
231
	    pVNC->updateBuf[pVNC->ublen++] = (char)bitmapByte;
232
	}
233
    }
234
235
    /* Update statistics. */
236
237
    cl->rfbCursorShapeBytesSent += (pVNC->ublen - saved_ublen);
238
    cl->rfbCursorShapeUpdatesSent++;
239
240
    return TRUE;
241
}
242
243
/*
244
 * Send cursor position (PointerPos pseudo-encoding).
245
 */
246
Bool
247
rfbSendCursorPos(cl, pScreen)
248
    rfbClientPtr cl;
249
    ScreenPtr pScreen;
250
{
251
    VNCSCREENPTR(pScreen);
252
    rfbFramebufferUpdateRectHeader rect;
253
#if XFREE86VNC
254
    ScreenPtr   pCursorScreen = miPointerCurrentScreen(); /*XXX deprecated*/
255
#endif
256
    int x, y;
257
258
    if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
259
	if (!rfbSendUpdateBuf(cl))
260
	    return FALSE;
261
    }
262
263
#if XFREE86VNC
264
    if (pScreen == pCursorScreen) 
265
        miPointerPosition(&x, &y);
266
#else
267
    rfbSpriteGetCursorPos(pScreen, &x, &y);
268
#endif
269
270
    rect.encoding = Swap32IfLE(rfbEncodingPointerPos);
271
    rect.r.x = Swap16IfLE((CARD16)x);
272
    rect.r.y = Swap16IfLE((CARD16)y);
273
    rect.r.w = 0;
274
    rect.r.h = 0;
275
276
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,
277
	   sz_rfbFramebufferUpdateRectHeader);
278
    pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
279
280
    cl->rfbCursorPosBytesSent += sz_rfbFramebufferUpdateRectHeader;
281
    cl->rfbCursorPosUpdatesSent++;
282
283
    if (!rfbSendUpdateBuf(cl))
284
	return FALSE;
285
286
    cl->cursorX = x;
287
    cl->cursorY = y;
288
289
    return TRUE;
290
}
291
292
/*
293
 * Code to convert cursor source bitmap to the desired pixel format.
294
 */
295
296
#define RGB48_TO_PIXEL(fmt,r,g,b)					\
297
    (((CARD32)(r) * ((fmt)->redMax + 1) >> 16) << (fmt)->redShift |	\
298
     ((CARD32)(g) * ((fmt)->greenMax + 1) >> 16) << (fmt)->greenShift |	\
299
     ((CARD32)(b) * ((fmt)->blueMax + 1) >> 16) << (fmt)->blueShift)
300
301
static int
302
EncodeRichCursorData8(buf, fmt, pCursor)
303
    unsigned char *buf;
304
    rfbPixelFormat *fmt;
305
    CursorPtr pCursor;
306
{
307
    int widthPixels, widthBytes;
308
    int x, y, b;
309
    CARD8 *src;
310
    char pix[2];
311
    CARD8 bitmapByte;
312
313
    pix[0] = (char)RGB48_TO_PIXEL(fmt, pCursor->backRed, pCursor->backGreen,
314
				  pCursor->backBlue);
315
    pix[1] = (char)RGB48_TO_PIXEL(fmt, pCursor->foreRed, pCursor->foreGreen,
316
				  pCursor->foreBlue);
317
318
    src = (CARD8 *)pCursor->bits->source;
319
    widthPixels = pCursor->bits->width;
320
    widthBytes = PixmapBytePad(widthPixels, 1);
321
322
    for (y = 0; y < pCursor->bits->height; y++) {
323
	for (x = 0; x < widthPixels / 8; x++) {
324
	    bitmapByte = src[y * widthBytes + x];
325
	    if (screenInfo.bitmapBitOrder == LSBFirst) {
326
		bitmapByte = _reverse_byte[bitmapByte];
327
	    }
328
	    for (b = 7; b >= 0; b--) {
329
		*buf++ = pix[bitmapByte >> b & 1];
330
	    }
331
	}
332
	if (widthPixels % 8) {
333
	    bitmapByte = src[y * widthBytes + x];
334
	    if (screenInfo.bitmapBitOrder == LSBFirst) {
335
		bitmapByte = _reverse_byte[bitmapByte];
336
	    }
337
	    for (b = 7; b > 7 - widthPixels % 8; b--) {
338
		*buf++ = pix[bitmapByte >> b & 1];
339
	    }
340
	}
341
    }
342
343
    return (widthPixels * pCursor->bits->height);
344
}
345
346
#define DEFINE_RICH_ENCODE(bpp)						 \
347
									 \
348
static int								 \
349
EncodeRichCursorData##bpp(pScreen, buf, fmt, pCursor)			 \
350
    ScreenPtr pScreen;							 \
351
    unsigned char *buf;							 \
352
    rfbPixelFormat *fmt;						 \
353
    CursorPtr pCursor;							 \
354
{									 \
355
    VNCSCREENPTR(pScreen);						 \
356
    int widthPixels, widthBytes;					 \
357
    int x, y, b;							 \
358
    CARD8 *src;								 \
359
    CARD##bpp pix[2];							 \
360
    CARD8 bitmapByte;							 \
361
									 \
362
    pix[0] = (CARD##bpp)RGB48_TO_PIXEL(fmt, pCursor->backRed,		 \
363
				       pCursor->backGreen,		 \
364
				       pCursor->backBlue);		 \
365
    pix[1] = (CARD##bpp)RGB48_TO_PIXEL(fmt, pCursor->foreRed,		 \
366
				       pCursor->foreGreen,		 \
367
				       pCursor->foreBlue);		 \
368
    if (!pVNC->rfbServerFormat.bigEndian != !fmt->bigEndian) {		 \
369
	pix[0] = Swap##bpp(pix[0]);					 \
370
	pix[1] = Swap##bpp(pix[1]);					 \
371
    }									 \
372
									 \
373
    src = (CARD8 *)pCursor->bits->source;				 \
374
    widthPixels = pCursor->bits->width;					 \
375
    widthBytes = PixmapBytePad(widthPixels, 1);				 \
376
									 \
377
    for (y = 0; y < pCursor->bits->height; y++) {			 \
378
	for (x = 0; x < widthPixels / 8; x++) {				 \
379
	    bitmapByte = src[y * widthBytes + x];			 \
380
	    if (screenInfo.bitmapBitOrder == LSBFirst) {		 \
381
		bitmapByte = _reverse_byte[bitmapByte];			 \
382
	    }								 \
383
	    for (b = 7; b >= 0; b--) {					 \
384
		memcpy (buf, (char *)&pix[bitmapByte >> b & 1],		 \
385
			sizeof(CARD##bpp));				 \
386
		buf += sizeof(CARD##bpp);				 \
387
	    }								 \
388
	}								 \
389
	if (widthPixels % 8) {						 \
390
	    bitmapByte = src[y * widthBytes + x];			 \
391
	    if (screenInfo.bitmapBitOrder == LSBFirst) {		 \
392
		bitmapByte = _reverse_byte[bitmapByte];			 \
393
	    }								 \
394
	    for (b = 7; b > 7 - widthPixels % 8; b--) {			 \
395
		memcpy (buf, (char *)&pix[bitmapByte >> b & 1],		 \
396
			sizeof(CARD##bpp));				 \
397
		buf += sizeof(CARD##bpp);				 \
398
	    }								 \
399
	}								 \
400
    }									 \
401
									 \
402
    return (widthPixels * pCursor->bits->height * (bpp / 8));		 \
403
}
404
405
DEFINE_RICH_ENCODE(16)
406
DEFINE_RICH_ENCODE(32)
407
(-)xorg-server-1.4.orig/hw/vnc/cutpaste.c (+90 lines)
Line 0 Link Here
1
/*
2
 * cutpaste.c - routines to deal with cut & paste buffers / selection.
3
 *
4
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
5
 */
6
7
/*
8
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
9
 *
10
 *  This is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  This software is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this software; if not, write to the Free Software
22
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
23
 *  USA.
24
 */
25
#ifdef HAVE_DIX_CONFIG_H
26
#include <dix-config.h>
27
#endif
28
29
#include <stdio.h>
30
#define NEED_EVENTS
31
#include <X11/X.h>
32
#include <X11/Xproto.h>
33
#include "rfb.h"
34
#include "selection.h"
35
#include "input.h"
36
#include <X11/Xatom.h>
37
38
extern Selection *CurrentSelections;
39
extern int NumCurrentSelections;
40
41
42
static Bool inSetXCutText = FALSE;
43
44
/*
45
 * rfbSetXCutText sets the cut buffer to be the given string.  We also clear
46
 * the primary selection.  Ideally we'd like to set it to the same thing, but I
47
 * can't work out how to do that without some kind of helper X client.
48
 */
49
50
void
51
rfbSetXCutText(char *str, int len)
52
{
53
    int i = 0;
54
55
    inSetXCutText = TRUE;
56
    ChangeWindowProperty(WindowTable[0], XA_CUT_BUFFER0, XA_STRING,
57
			 8, PropModeReplace, len,
58
			 (pointer)str, TRUE);
59
    
60
    while ((i < NumCurrentSelections) && 
61
	   CurrentSelections[i].selection != XA_PRIMARY)
62
	i++;
63
64
    if (i < NumCurrentSelections) {
65
	xEvent event;
66
67
	if (CurrentSelections[i].client) {
68
	    event.u.u.type = SelectionClear;
69
	    event.u.selectionClear.time = GetTimeInMillis();
70
	    event.u.selectionClear.window = CurrentSelections[i].window;
71
	    event.u.selectionClear.atom = CurrentSelections[i].selection;
72
	    (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
73
				NoEventMask, NoEventMask /* CantBeFiltered */,
74
				NullGrab);
75
	}
76
77
	CurrentSelections[i].window = None;
78
	CurrentSelections[i].pWin = NULL;
79
	CurrentSelections[i].client = NullClient;
80
    }
81
82
    inSetXCutText = FALSE;
83
}
84
85
86
void rfbGotXCutText(char *str, int len)
87
{
88
    if (!inSetXCutText)
89
	rfbSendServerCutText(str, len);
90
}
(-)xorg-server-1.4.orig/hw/vnc/d3des.c (+437 lines)
Line 0 Link Here
1
/*
2
 * This is D3DES (V5.09) by Richard Outerbridge with the double and
3
 * triple-length support removed for use in VNC.  Also the bytebit[] array
4
 * has been reversed so that the most significant bit in each byte of the
5
 * key is ignored, not the least significant.
6
 *
7
 * These changes are:
8
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
9
 *
10
 * This software is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/* D3DES (V5.09) -
16
 *
17
 * A portable, public domain, version of the Data Encryption Standard.
18
 *
19
 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
20
 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
21
 * code;  Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
22
 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
23
 * for humouring me on.
24
 *
25
 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
26
 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
27
 */
28
#ifdef HAVE_DIX_CONFIG_H
29
#include <dix-config.h>
30
#endif
31
32
#include "d3des.h"
33
34
static void scrunch(unsigned char *, unsigned long *);
35
static void unscrun(unsigned long *, unsigned char *);
36
static void desfunc(unsigned long *, unsigned long *);
37
static void cookey(unsigned long *);
38
39
static unsigned long KnL[32] = { 0L };
40
41
static unsigned short bytebit[8]	= {
42
	01, 02, 04, 010, 020, 040, 0100, 0200 };
43
44
static unsigned long bigbyte[24] = {
45
	0x800000L,	0x400000L,	0x200000L,	0x100000L,
46
	0x80000L,	0x40000L,	0x20000L,	0x10000L,
47
	0x8000L,	0x4000L,	0x2000L,	0x1000L,
48
	0x800L, 	0x400L, 	0x200L, 	0x100L,
49
	0x80L,		0x40L,		0x20L,		0x10L,
50
	0x8L,		0x4L,		0x2L,		0x1L	};
51
52
/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
53
54
static unsigned char pc1[56] = {
55
	56, 48, 40, 32, 24, 16,  8,	 0, 57, 49, 41, 33, 25, 17,
56
	 9,  1, 58, 50, 42, 34, 26,	18, 10,  2, 59, 51, 43, 35,
57
	62, 54, 46, 38, 30, 22, 14,	 6, 61, 53, 45, 37, 29, 21,
58
	13,  5, 60, 52, 44, 36, 28,	20, 12,  4, 27, 19, 11,  3 };
59
60
static unsigned char totrot[16] = {
61
	1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
62
63
static unsigned char pc2[48] = {
64
	13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
65
	22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
66
	40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
67
	43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
68
69
void deskey(key, edf)	/* Thanks to James Gillogly & Phil Karn! */
70
unsigned char *key;
71
int edf;
72
{
73
	register int i, j, l, m, n;
74
	unsigned char pc1m[56], pcr[56];
75
	unsigned long kn[32];
76
77
	for ( j = 0; j < 56; j++ ) {
78
		l = pc1[j];
79
		m = l & 07;
80
		pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
81
		}
82
	for( i = 0; i < 16; i++ ) {
83
		if( edf == DE1 ) m = (15 - i) << 1;
84
		else m = i << 1;
85
		n = m + 1;
86
		kn[m] = kn[n] = 0L;
87
		for( j = 0; j < 28; j++ ) {
88
			l = j + totrot[i];
89
			if( l < 28 ) pcr[j] = pc1m[l];
90
			else pcr[j] = pc1m[l - 28];
91
			}
92
		for( j = 28; j < 56; j++ ) {
93
		    l = j + totrot[i];
94
		    if( l < 56 ) pcr[j] = pc1m[l];
95
		    else pcr[j] = pc1m[l - 28];
96
		    }
97
		for( j = 0; j < 24; j++ ) {
98
			if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
99
			if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
100
			}
101
		}
102
	cookey(kn);
103
	return;
104
	}
105
106
static void cookey(raw1)
107
register unsigned long *raw1;
108
{
109
	register unsigned long *cook, *raw0;
110
	unsigned long dough[32];
111
	register int i;
112
113
	cook = dough;
114
	for( i = 0; i < 16; i++, raw1++ ) {
115
		raw0 = raw1++;
116
		*cook	 = (*raw0 & 0x00fc0000L) << 6;
117
		*cook	|= (*raw0 & 0x00000fc0L) << 10;
118
		*cook	|= (*raw1 & 0x00fc0000L) >> 10;
119
		*cook++ |= (*raw1 & 0x00000fc0L) >> 6;
120
		*cook	 = (*raw0 & 0x0003f000L) << 12;
121
		*cook	|= (*raw0 & 0x0000003fL) << 16;
122
		*cook	|= (*raw1 & 0x0003f000L) >> 4;
123
		*cook++ |= (*raw1 & 0x0000003fL);
124
		}
125
	usekey(dough);
126
	return;
127
	}
128
129
void cpkey(into)
130
register unsigned long *into;
131
{
132
	register unsigned long *from, *endp;
133
134
	from = KnL, endp = &KnL[32];
135
	while( from < endp ) *into++ = *from++;
136
	return;
137
	}
138
139
void usekey(from)
140
register unsigned long *from;
141
{
142
	register unsigned long *to, *endp;
143
144
	to = KnL, endp = &KnL[32];
145
	while( to < endp ) *to++ = *from++;
146
	return;
147
	}
148
149
void des(inblock, outblock)
150
unsigned char *inblock, *outblock;
151
{
152
	unsigned long work[2];
153
154
	scrunch(inblock, work);
155
	desfunc(work, KnL);
156
	unscrun(work, outblock);
157
	return;
158
	}
159
160
static void scrunch(outof, into)
161
register unsigned char *outof;
162
register unsigned long *into;
163
{
164
	*into	 = (*outof++ & 0xffL) << 24;
165
	*into	|= (*outof++ & 0xffL) << 16;
166
	*into	|= (*outof++ & 0xffL) << 8;
167
	*into++ |= (*outof++ & 0xffL);
168
	*into	 = (*outof++ & 0xffL) << 24;
169
	*into	|= (*outof++ & 0xffL) << 16;
170
	*into	|= (*outof++ & 0xffL) << 8;
171
	*into	|= (*outof   & 0xffL);
172
	return;
173
	}
174
175
static void unscrun(outof, into)
176
register unsigned long *outof;
177
register unsigned char *into;
178
{
179
	*into++ = (*outof >> 24) & 0xffL;
180
	*into++ = (*outof >> 16) & 0xffL;
181
	*into++ = (*outof >>  8) & 0xffL;
182
	*into++ =  *outof++	 & 0xffL;
183
	*into++ = (*outof >> 24) & 0xffL;
184
	*into++ = (*outof >> 16) & 0xffL;
185
	*into++ = (*outof >>  8) & 0xffL;
186
	*into	=  *outof	 & 0xffL;
187
	return;
188
	}
189
190
static unsigned long SP1[64] = {
191
	0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
192
	0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
193
	0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
194
	0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
195
	0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
196
	0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
197
	0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
198
	0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
199
	0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
200
	0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
201
	0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
202
	0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
203
	0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
204
	0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
205
	0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
206
	0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
207
208
static unsigned long SP2[64] = {
209
	0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
210
	0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
211
	0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
212
	0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
213
	0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
214
	0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
215
	0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
216
	0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
217
	0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
218
	0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
219
	0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
220
	0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
221
	0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
222
	0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
223
	0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
224
	0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
225
226
static unsigned long SP3[64] = {
227
	0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
228
	0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
229
	0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
230
	0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
231
	0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
232
	0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
233
	0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
234
	0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
235
	0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
236
	0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
237
	0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
238
	0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
239
	0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
240
	0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
241
	0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
242
	0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
243
244
static unsigned long SP4[64] = {
245
	0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
246
	0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
247
	0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
248
	0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
249
	0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
250
	0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
251
	0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
252
	0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
253
	0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
254
	0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
255
	0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
256
	0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
257
	0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
258
	0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
259
	0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
260
	0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
261
262
static unsigned long SP5[64] = {
263
	0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
264
	0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
265
	0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
266
	0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
267
	0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
268
	0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
269
	0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
270
	0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
271
	0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
272
	0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
273
	0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
274
	0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
275
	0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
276
	0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
277
	0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
278
	0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
279
280
static unsigned long SP6[64] = {
281
	0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
282
	0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
283
	0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
284
	0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
285
	0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
286
	0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
287
	0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
288
	0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
289
	0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
290
	0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
291
	0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
292
	0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
293
	0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
294
	0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
295
	0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
296
	0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
297
298
static unsigned long SP7[64] = {
299
	0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
300
	0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
301
	0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
302
	0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
303
	0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
304
	0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
305
	0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
306
	0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
307
	0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
308
	0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
309
	0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
310
	0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
311
	0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
312
	0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
313
	0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
314
	0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
315
316
static unsigned long SP8[64] = {
317
	0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
318
	0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
319
	0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
320
	0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
321
	0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
322
	0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
323
	0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
324
	0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
325
	0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
326
	0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
327
	0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
328
	0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
329
	0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
330
	0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
331
	0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
332
	0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
333
334
static void desfunc(block, keys)
335
register unsigned long *block, *keys;
336
{
337
	register unsigned long fval, work, right, leftt;
338
	register int round;
339
340
	leftt = block[0];
341
	right = block[1];
342
	work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
343
	right ^= work;
344
	leftt ^= (work << 4);
345
	work = ((leftt >> 16) ^ right) & 0x0000ffffL;
346
	right ^= work;
347
	leftt ^= (work << 16);
348
	work = ((right >> 2) ^ leftt) & 0x33333333L;
349
	leftt ^= work;
350
	right ^= (work << 2);
351
	work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
352
	leftt ^= work;
353
	right ^= (work << 8);
354
	right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
355
	work = (leftt ^ right) & 0xaaaaaaaaL;
356
	leftt ^= work;
357
	right ^= work;
358
	leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
359
360
	for( round = 0; round < 8; round++ ) {
361
		work  = (right << 28) | (right >> 4);
362
		work ^= *keys++;
363
		fval  = SP7[ work		 & 0x3fL];
364
		fval |= SP5[(work >>  8) & 0x3fL];
365
		fval |= SP3[(work >> 16) & 0x3fL];
366
		fval |= SP1[(work >> 24) & 0x3fL];
367
		work  = right ^ *keys++;
368
		fval |= SP8[ work		 & 0x3fL];
369
		fval |= SP6[(work >>  8) & 0x3fL];
370
		fval |= SP4[(work >> 16) & 0x3fL];
371
		fval |= SP2[(work >> 24) & 0x3fL];
372
		leftt ^= fval;
373
		work  = (leftt << 28) | (leftt >> 4);
374
		work ^= *keys++;
375
		fval  = SP7[ work		 & 0x3fL];
376
		fval |= SP5[(work >>  8) & 0x3fL];
377
		fval |= SP3[(work >> 16) & 0x3fL];
378
		fval |= SP1[(work >> 24) & 0x3fL];
379
		work  = leftt ^ *keys++;
380
		fval |= SP8[ work		 & 0x3fL];
381
		fval |= SP6[(work >>  8) & 0x3fL];
382
		fval |= SP4[(work >> 16) & 0x3fL];
383
		fval |= SP2[(work >> 24) & 0x3fL];
384
		right ^= fval;
385
		}
386
387
	right = (right << 31) | (right >> 1);
388
	work = (leftt ^ right) & 0xaaaaaaaaL;
389
	leftt ^= work;
390
	right ^= work;
391
	leftt = (leftt << 31) | (leftt >> 1);
392
	work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
393
	right ^= work;
394
	leftt ^= (work << 8);
395
	work = ((leftt >> 2) ^ right) & 0x33333333L;
396
	right ^= work;
397
	leftt ^= (work << 2);
398
	work = ((right >> 16) ^ leftt) & 0x0000ffffL;
399
	leftt ^= work;
400
	right ^= (work << 16);
401
	work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
402
	leftt ^= work;
403
	right ^= (work << 4);
404
	*block++ = right;
405
	*block = leftt;
406
	return;
407
	}
408
409
/* Validation sets:
410
 *
411
 * Single-length key, single-length plaintext -
412
 * Key	  : 0123 4567 89ab cdef
413
 * Plain  : 0123 4567 89ab cde7
414
 * Cipher : c957 4425 6a5e d31d
415
 *
416
 * Double-length key, single-length plaintext -
417
 * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210
418
 * Plain  : 0123 4567 89ab cde7
419
 * Cipher : 7f1d 0a77 826b 8aff
420
 *
421
 * Double-length key, double-length plaintext -
422
 * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210
423
 * Plain  : 0123 4567 89ab cdef 0123 4567 89ab cdff
424
 * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
425
 *
426
 * Triple-length key, single-length plaintext -
427
 * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
428
 * Plain  : 0123 4567 89ab cde7
429
 * Cipher : de0b 7c06 ae5e 0ed5
430
 *
431
 * Triple-length key, double-length plaintext -
432
 * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
433
 * Plain  : 0123 4567 89ab cdef 0123 4567 89ab cdff
434
 * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
435
 *
436
 * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
437
 **********************************************************************/
(-)xorg-server-1.4.orig/hw/vnc/d3des.h (+51 lines)
Line 0 Link Here
1
/*
2
 * This is D3DES (V5.09) by Richard Outerbridge with the double and
3
 * triple-length support removed for use in VNC.
4
 *
5
 * These changes are:
6
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
7
 *
8
 * This software is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 */
12
13
/* d3des.h -
14
 *
15
 *	Headers and defines for d3des.c
16
 *	Graven Imagery, 1992.
17
 *
18
 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
19
 *	(GEnie : OUTER; CIS : [71755,204])
20
 */
21
22
#define EN0	0	/* MODE == encrypt */
23
#define DE1	1	/* MODE == decrypt */
24
25
extern void deskey(unsigned char *, int);
26
/*		      hexkey[8]     MODE
27
 * Sets the internal key register according to the hexadecimal
28
 * key contained in the 8 bytes of hexkey, according to the DES,
29
 * for encryption or decryption according to MODE.
30
 */
31
32
extern void usekey(unsigned long *);
33
/*		    cookedkey[32]
34
 * Loads the internal key register with the data in cookedkey.
35
 */
36
37
extern void cpkey(unsigned long *);
38
/*		   cookedkey[32]
39
 * Copies the contents of the internal key register into the storage
40
 * located at &cookedkey[0].
41
 */
42
43
extern void des(unsigned char *, unsigned char *);
44
/*		    from[8]	      to[8]
45
 * Encrypts/Decrypts (according to the key currently loaded in the
46
 * internal key register) one block of eight bytes at address 'from'
47
 * into the block at address 'to'.  They can be the same.
48
 */
49
50
/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
51
 ********************************************************************/
(-)xorg-server-1.4.orig/hw/vnc/dispcur.c (+791 lines)
Line 0 Link Here
1
/*
2
 * dispcur.c
3
 *
4
 * cursor display routines - based on midispcur.c
5
 *
6
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
7
 */
8
9
/*
10
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
11
 *
12
 *  This is free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 2 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  This software is distributed in the hope that it will be useful,
18
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 *  GNU General Public License for more details.
21
 *
22
 *  You should have received a copy of the GNU General Public License
23
 *  along with this software; if not, write to the Free Software
24
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
25
 *  USA.
26
 */
27
28
/*
29
30
Copyright (c) 1989  X Consortium
31
32
Permission is hereby granted, free of charge, to any person obtaining a copy
33
of this software and associated documentation files (the "Software"), to deal
34
in the Software without restriction, including without limitation the rights
35
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
copies of the Software, and to permit persons to whom the Software is
37
furnished to do so, subject to the following conditions:
38
39
The above copyright notice and this permission notice shall be included in
40
all copies or substantial portions of the Software.
41
42
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
45
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
46
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
47
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48
49
Except as contained in this notice, the name of the X Consortium shall not be
50
used in advertising or otherwise to promote the sale, use or other dealings
51
in this Software without prior written authorization from the X Consortium.
52
*/
53
#ifdef HAVE_DIX_CONFIG_H
54
#include <dix-config.h>
55
#endif
56
57
#define NEED_EVENTS
58
# include   <X11/X.h>
59
# include   "rfb.h"
60
# include   "misc.h"
61
# include   "input.h"
62
# include   "cursorstr.h"
63
# include   "windowstr.h"
64
# include   "regionstr.h"
65
# include   "dixstruct.h"
66
# include   "scrnintstr.h"
67
# include   "servermd.h"
68
# include   "sprite.h"
69
# include   "gcstruct.h"
70
71
#ifdef ARGB_CURSOR
72
# include   "picturestr.h"
73
#endif
74
75
/* per-screen private data */
76
77
static int	rfbDCScreenIndex;
78
static unsigned long rfbDCGeneration = 0;
79
80
static Bool	rfbDCCloseScreen(int index, ScreenPtr pScreen);
81
82
typedef struct {
83
    GCPtr	    pSourceGC, pMaskGC;
84
    GCPtr	    pSaveGC, pRestoreGC;
85
    GCPtr	    pMoveGC;
86
    GCPtr	    pPixSourceGC, pPixMaskGC;
87
    CloseScreenProcPtr CloseScreen;
88
    PixmapPtr	    pSave, pTemp;
89
#ifdef ARGB_CURSOR
90
    PicturePtr      pRootPicture;
91
    PicturePtr      pTempPicture;
92
#endif
93
} rfbDCScreenRec, *rfbDCScreenPtr;
94
95
/* per-cursor per-screen private data */
96
typedef struct {
97
    PixmapPtr		sourceBits;	    /* source bits */
98
    PixmapPtr		maskBits;	    /* mask bits */
99
#ifdef ARGB_CURSOR
100
    PicturePtr          pPicture;
101
#endif
102
} rfbDCCursorRec, *rfbDCCursorPtr;
103
104
/*
105
 * sprite/cursor method table
106
 */
107
108
static Bool	rfbDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
109
static Bool	rfbDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
110
static Bool	rfbDCPutUpCursor(ScreenPtr pScreen, CursorPtr pCursor,
111
				int x, int y, unsigned long source,
112
				unsigned long mask);
113
static Bool	rfbDCSaveUnderCursor(ScreenPtr pScreen, int x, int y,
114
				    int w, int h);
115
static Bool	rfbDCRestoreUnderCursor(ScreenPtr pScreen, int x, int y,
116
				       int w, int h);
117
static Bool	rfbDCMoveCursor(ScreenPtr pScreen, CursorPtr pCursor,
118
			       int x, int y, int w, int h, int dx, int dy,
119
			       unsigned long source, unsigned long mask);
120
static Bool	rfbDCChangeSave(ScreenPtr pScreen, int x, int y, int w, int h,	
121
			       int dx, int dy);
122
123
static rfbSpriteCursorFuncRec rfbDCFuncs = {
124
    rfbDCRealizeCursor,
125
    rfbDCUnrealizeCursor,
126
    rfbDCPutUpCursor,
127
    rfbDCSaveUnderCursor,
128
    rfbDCRestoreUnderCursor,
129
    rfbDCMoveCursor,
130
    rfbDCChangeSave,
131
};
132
133
Bool
134
rfbDCInitialize (ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
135
{
136
    rfbDCScreenPtr   pScreenPriv;
137
138
    if (rfbDCGeneration != serverGeneration)
139
    {
140
	rfbDCScreenIndex = AllocateScreenPrivateIndex ();
141
	if (rfbDCScreenIndex < 0)
142
	    return FALSE;
143
	rfbDCGeneration = serverGeneration;
144
    }
145
    pScreenPriv = (rfbDCScreenPtr) xalloc (sizeof (rfbDCScreenRec));
146
    if (!pScreenPriv)
147
	return FALSE;
148
149
    /*
150
     * initialize the entire private structure to zeros
151
     */
152
153
    pScreenPriv->pSourceGC =
154
	pScreenPriv->pMaskGC =
155
	pScreenPriv->pSaveGC =
156
 	pScreenPriv->pRestoreGC =
157
	pScreenPriv->pMoveGC =
158
 	pScreenPriv->pPixSourceGC =
159
	pScreenPriv->pPixMaskGC = NULL;
160
#ifdef ARGB_CURSOR
161
    pScreenPriv->pRootPicture = NULL;
162
    pScreenPriv->pTempPicture = NULL;
163
#endif
164
    
165
    pScreenPriv->pSave = pScreenPriv->pTemp = NULL;
166
167
    pScreenPriv->CloseScreen = pScreen->CloseScreen;
168
    pScreen->CloseScreen = rfbDCCloseScreen;
169
    
170
    pScreen->devPrivates[rfbDCScreenIndex].ptr = (pointer) pScreenPriv;
171
172
    if (!rfbSpriteInitialize (pScreen, &rfbDCFuncs, screenFuncs))
173
    {
174
	xfree ((pointer) pScreenPriv);
175
	return FALSE;
176
    }
177
    return TRUE;
178
}
179
180
#define tossGC(gc)  (gc ? FreeGC (gc, (GContext) 0) : 0)
181
#define tossPix(pix)	(pix ? (*pScreen->DestroyPixmap) (pix) : TRUE)
182
#define tossPict(pict)  (pict ? FreePicture (pict, 0) : 0)
183
184
static Bool
185
rfbDCCloseScreen (index, pScreen)
186
    ScreenPtr	pScreen;
187
{
188
    rfbDCScreenPtr   pScreenPriv;
189
190
    pScreenPriv = (rfbDCScreenPtr) pScreen->devPrivates[rfbDCScreenIndex].ptr;
191
    pScreen->CloseScreen = pScreenPriv->CloseScreen;
192
    tossGC (pScreenPriv->pSourceGC);
193
    tossGC (pScreenPriv->pMaskGC);
194
    tossGC (pScreenPriv->pSaveGC);
195
    tossGC (pScreenPriv->pRestoreGC);
196
    tossGC (pScreenPriv->pMoveGC);
197
    tossGC (pScreenPriv->pPixSourceGC);
198
    tossGC (pScreenPriv->pPixMaskGC);
199
    tossPix (pScreenPriv->pSave);
200
    tossPix (pScreenPriv->pTemp);
201
#ifdef ARGB_CURSOR
202
    tossPict (pScreenPriv->pRootPicture);
203
    tossPict (pScreenPriv->pTempPicture);
204
#endif
205
    xfree ((pointer) pScreenPriv);
206
    return (*pScreen->CloseScreen) (index, pScreen);
207
}
208
209
static Bool
210
rfbDCRealizeCursor (pScreen, pCursor)
211
    ScreenPtr	pScreen;
212
    CursorPtr	pCursor;
213
{
214
    if (pCursor->bits->refcnt <= 1)
215
	pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL;
216
    return TRUE;
217
}
218
219
#ifdef ARGB_CURSOR
220
#define EnsurePicture(picture,draw,win) (picture || rfbDCMakePicture(&picture,draw,win))
221
222
static VisualPtr
223
rfbDCGetWindowVisual (WindowPtr pWin)
224
{
225
    ScreenPtr	    pScreen = pWin->drawable.pScreen;
226
    VisualID	    vid = wVisual (pWin);
227
    int		    i;
228
229
    for (i = 0; i < pScreen->numVisuals; i++)
230
	if (pScreen->visuals[i].vid == vid)
231
	    return &pScreen->visuals[i];
232
    return 0;
233
}
234
235
static PicturePtr
236
rfbDCMakePicture (PicturePtr *ppPicture, DrawablePtr pDraw, WindowPtr pWin)
237
{
238
    ScreenPtr	    pScreen = pDraw->pScreen;
239
    VisualPtr	    pVisual;
240
    PictFormatPtr   pFormat;
241
    XID		    subwindow_mode = IncludeInferiors;
242
    PicturePtr	    pPicture;
243
    int		    error;
244
    
245
    pVisual = rfbDCGetWindowVisual (pWin);
246
    if (!pVisual)
247
	return 0;
248
    pFormat = PictureMatchVisual (pScreen, pDraw->depth, pVisual);
249
    if (!pFormat)
250
	return 0;
251
    pPicture = CreatePicture (0, pDraw, pFormat,
252
			      CPSubwindowMode, &subwindow_mode,
253
			      serverClient, &error);
254
    *ppPicture = pPicture;
255
    return pPicture;
256
}
257
#endif
258
259
static rfbDCCursorPtr
260
rfbDCRealize (ScreenPtr pScreen, CursorPtr pCursor)
261
{
262
    rfbDCCursorPtr   pPriv;
263
    GCPtr	    pGC;
264
    XID		    gcvals[3];
265
266
    pPriv = (rfbDCCursorPtr) xalloc (sizeof (rfbDCCursorRec));
267
    if (!pPriv)
268
	return (rfbDCCursorPtr)NULL;
269
#ifdef ARGB_CURSOR
270
    if (pCursor->bits->argb)
271
    {
272
	PixmapPtr	pPixmap;
273
	PictFormatPtr	pFormat;
274
	int		error;
275
	
276
	pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
277
	if (!pFormat)
278
	{
279
	    xfree ((pointer) pPriv);
280
	    return (rfbDCCursorPtr)NULL;
281
	}
282
	
283
	pPriv->sourceBits = 0;
284
	pPriv->maskBits = 0;
285
	pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
286
					    pCursor->bits->height, 32);
287
	if (!pPixmap)
288
	{
289
	    xfree ((pointer) pPriv);
290
	    return (rfbDCCursorPtr)NULL;
291
	}
292
	pGC = GetScratchGC (32, pScreen);
293
	if (!pGC)
294
	{
295
	    (*pScreen->DestroyPixmap) (pPixmap);
296
	    xfree ((pointer) pPriv);
297
	    return (rfbDCCursorPtr)NULL;
298
	}
299
	ValidateGC (&pPixmap->drawable, pGC);
300
	(*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32,
301
			       0, 0, pCursor->bits->width,
302
			       pCursor->bits->height,
303
			       0, ZPixmap, (char *) pCursor->bits->argb);
304
	FreeScratchGC (pGC);
305
	pPriv->pPicture = CreatePicture (0, &pPixmap->drawable,
306
					pFormat, 0, 0, serverClient, &error);
307
        (*pScreen->DestroyPixmap) (pPixmap);
308
	if (!pPriv->pPicture)
309
	{
310
	    xfree ((pointer) pPriv);
311
	    return (rfbDCCursorPtr)NULL;
312
	}
313
	pCursor->bits->devPriv[pScreen->myNum] = (pointer) pPriv;
314
	return pPriv;
315
    }
316
    pPriv->pPicture = 0;
317
#endif
318
    pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1);
319
    if (!pPriv->sourceBits)
320
    {
321
	xfree ((pointer) pPriv);
322
	return (rfbDCCursorPtr)NULL;
323
    }
324
    pPriv->maskBits =  (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1);
325
    if (!pPriv->maskBits)
326
    {
327
	(*pScreen->DestroyPixmap) (pPriv->sourceBits);
328
	xfree ((pointer) pPriv);
329
	return (rfbDCCursorPtr)NULL;
330
    }
331
    pCursor->bits->devPriv[pScreen->myNum] = (pointer) pPriv;
332
333
    /* create the two sets of bits, clipping as appropriate */
334
335
    pGC = GetScratchGC (1, pScreen);
336
    if (!pGC)
337
    {
338
	(void) rfbDCUnrealizeCursor (pScreen, pCursor);
339
	return (rfbDCCursorPtr)NULL;
340
    }
341
342
    ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
343
    (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1,
344
			   0, 0, pCursor->bits->width, pCursor->bits->height,
345
 			   0, XYPixmap, (char *)pCursor->bits->source);
346
    gcvals[0] = GXand;
347
    ChangeGC (pGC, GCFunction, gcvals);
348
    ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
349
    (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1,
350
			   0, 0, pCursor->bits->width, pCursor->bits->height,
351
 			   0, XYPixmap, (char *)pCursor->bits->mask);
352
353
    /* mask bits -- pCursor->mask & ~pCursor->source */
354
    gcvals[0] = GXcopy;
355
    ChangeGC (pGC, GCFunction, gcvals);
356
    ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
357
    (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1,
358
			   0, 0, pCursor->bits->width, pCursor->bits->height,
359
 			   0, XYPixmap, (char *)pCursor->bits->mask);
360
    gcvals[0] = GXandInverted;
361
    ChangeGC (pGC, GCFunction, gcvals);
362
    ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
363
    (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1,
364
			   0, 0, pCursor->bits->width, pCursor->bits->height,
365
 			   0, XYPixmap, (char *)pCursor->bits->source);
366
    FreeScratchGC (pGC);
367
    return pPriv;
368
}
369
370
static Bool
371
rfbDCUnrealizeCursor (pScreen, pCursor)
372
    ScreenPtr	pScreen;
373
    CursorPtr	pCursor;
374
{
375
    rfbDCCursorPtr   pPriv;
376
377
    pPriv = (rfbDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
378
    if (pPriv && (pCursor->bits->refcnt <= 1))
379
    {
380
	if (pPriv->sourceBits)
381
	    (*pScreen->DestroyPixmap) (pPriv->sourceBits);
382
	if (pPriv->maskBits)
383
	    (*pScreen->DestroyPixmap) (pPriv->maskBits);
384
#ifdef ARGB_CURSOR
385
	if (pPriv->pPicture)
386
	    FreePicture (pPriv->pPicture, 0);
387
#endif
388
	xfree ((pointer) pPriv);
389
	pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL;
390
    }
391
    return TRUE;
392
}
393
394
static void
395
rfbDCPutBits (DrawablePtr pDrawable, rfbDCCursorPtr pPriv, GCPtr sourceGC, GCPtr maskGC, int x, int y, unsigned w, unsigned h, unsigned long source, unsigned long mask)
396
{
397
    XID	    gcvals[1];
398
399
    if (sourceGC->fgPixel != source)
400
    {
401
	gcvals[0] = source;
402
	DoChangeGC (sourceGC, GCForeground, gcvals, 0);
403
    }
404
    if (sourceGC->serialNumber != pDrawable->serialNumber)
405
	ValidateGC (pDrawable, sourceGC);
406
    (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y);
407
    if (maskGC->fgPixel != mask)
408
    {
409
	gcvals[0] = mask;
410
	DoChangeGC (maskGC, GCForeground, gcvals, 0);
411
    }
412
    if (maskGC->serialNumber != pDrawable->serialNumber)
413
	ValidateGC (pDrawable, maskGC);
414
    (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y);
415
}
416
417
#define EnsureGC(gc,win) (gc || rfbDCMakeGC(&gc, win))
418
419
static GCPtr
420
rfbDCMakeGC(GCPtr *ppGC, WindowPtr pWin)
421
{
422
    GCPtr pGC;
423
    int   status;
424
    XID   gcvals[2];
425
426
    gcvals[0] = IncludeInferiors;
427
    gcvals[1] = FALSE;
428
    pGC = CreateGC((DrawablePtr)pWin,
429
		   GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
430
    if (pGC && pWin->drawable.pScreen->DrawGuarantee)
431
	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
432
    *ppGC = pGC;
433
    return pGC;
434
}
435
436
static Bool
437
rfbDCPutUpCursor (pScreen, pCursor, x, y, source, mask)
438
    ScreenPtr	    pScreen;
439
    CursorPtr	    pCursor;
440
    int		    x, y;
441
    unsigned long   source, mask;
442
{
443
    rfbDCScreenPtr   pScreenPriv;
444
    rfbDCCursorPtr   pPriv;
445
    WindowPtr	    pWin;
446
447
    pPriv = (rfbDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
448
    if (!pPriv)
449
    {
450
	pPriv = rfbDCRealize(pScreen, pCursor);
451
	if (!pPriv)
452
	    return FALSE;
453
    }
454
    pScreenPriv = (rfbDCScreenPtr) pScreen->devPrivates[rfbDCScreenIndex].ptr;
455
    pWin = WindowTable[pScreen->myNum];
456
#ifdef ARGB_CURSOR
457
    if (pPriv->pPicture)
458
    {
459
	if (!EnsurePicture(pScreenPriv->pRootPicture, &pWin->drawable, pWin))
460
	    return FALSE;
461
	CompositePicture (PictOpOver,
462
			  pPriv->pPicture,
463
			  NULL,
464
			  pScreenPriv->pRootPicture,
465
			  0, 0, 0, 0, 
466
			  x, y, 
467
			  pCursor->bits->width,
468
			  pCursor->bits->height);
469
    }
470
    else
471
#endif
472
    {
473
	if (!EnsureGC(pScreenPriv->pSourceGC, pWin))
474
	    return FALSE;
475
	if (!EnsureGC(pScreenPriv->pMaskGC, pWin))
476
	{
477
	    FreeGC (pScreenPriv->pSourceGC, (GContext) 0);
478
	    pScreenPriv->pSourceGC = 0;
479
	    return FALSE;
480
	}
481
	rfbDCPutBits ((DrawablePtr)pWin, pPriv,
482
		     pScreenPriv->pSourceGC, pScreenPriv->pMaskGC,
483
		     x, y, pCursor->bits->width, pCursor->bits->height,
484
		     source, mask);
485
    }
486
    return TRUE;
487
}
488
489
static Bool
490
rfbDCSaveUnderCursor (pScreen, x, y, w, h)
491
    ScreenPtr	pScreen;
492
    int		x, y, w, h;
493
{
494
    rfbDCScreenPtr   pScreenPriv;
495
    PixmapPtr	    pSave;
496
    WindowPtr	    pWin;
497
    GCPtr	    pGC;
498
499
    pScreenPriv = (rfbDCScreenPtr) pScreen->devPrivates[rfbDCScreenIndex].ptr;
500
    pSave = pScreenPriv->pSave;
501
    pWin = WindowTable[pScreen->myNum];
502
    if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h)
503
    {
504
	if (pSave)
505
	    (*pScreen->DestroyPixmap) (pSave);
506
	pScreenPriv->pSave = pSave =
507
		(*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth);
508
	if (!pSave)
509
	    return FALSE;
510
    }
511
    if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
512
	return FALSE;
513
    pGC = pScreenPriv->pSaveGC;
514
    if (pSave->drawable.serialNumber != pGC->serialNumber)
515
	ValidateGC ((DrawablePtr) pSave, pGC);
516
    (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
517
			    x, y, w, h, 0, 0);
518
    return TRUE;
519
}
520
521
static Bool
522
rfbDCRestoreUnderCursor (pScreen, x, y, w, h)
523
    ScreenPtr	pScreen;
524
    int		x, y, w, h;
525
{
526
    rfbDCScreenPtr   pScreenPriv;
527
    PixmapPtr	    pSave;
528
    WindowPtr	    pWin;
529
    GCPtr	    pGC;
530
531
    pScreenPriv = (rfbDCScreenPtr) pScreen->devPrivates[rfbDCScreenIndex].ptr;
532
    pSave = pScreenPriv->pSave;
533
    pWin = WindowTable[pScreen->myNum];
534
    if (!pSave)
535
	return FALSE;
536
    if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
537
	return FALSE;
538
    pGC = pScreenPriv->pRestoreGC;
539
    if (pWin->drawable.serialNumber != pGC->serialNumber)
540
	ValidateGC ((DrawablePtr) pWin, pGC);
541
    (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
542
			    0, 0, w, h, x, y);
543
    return TRUE;
544
}
545
546
static Bool
547
rfbDCChangeSave (pScreen, x, y, w, h, dx, dy)
548
    ScreenPtr	    pScreen;
549
    int		    x, y, w, h, dx, dy;
550
{
551
    rfbDCScreenPtr   pScreenPriv;
552
    PixmapPtr	    pSave;
553
    WindowPtr	    pWin;
554
    GCPtr	    pGC;
555
    int		    sourcex, sourcey, destx, desty, copyw, copyh;
556
557
    pScreenPriv = (rfbDCScreenPtr) pScreen->devPrivates[rfbDCScreenIndex].ptr;
558
    pSave = pScreenPriv->pSave;
559
    pWin = WindowTable[pScreen->myNum];
560
    /*
561
     * restore the bits which are about to get trashed
562
     */
563
    if (!pSave)
564
	return FALSE;
565
    if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
566
	return FALSE;
567
    pGC = pScreenPriv->pRestoreGC;
568
    if (pWin->drawable.serialNumber != pGC->serialNumber)
569
	ValidateGC ((DrawablePtr) pWin, pGC);
570
    /*
571
     * copy the old bits to the screen.
572
     */
573
    if (dy > 0)
574
    {
575
	(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
576
			       0, h - dy, w, dy, x + dx, y + h);
577
    }
578
    else if (dy < 0)
579
    {
580
	(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
581
			       0, 0, w, -dy, x + dx, y + dy);
582
    }
583
    if (dy >= 0)
584
    {
585
	desty = y + dy;
586
	sourcey = 0;
587
	copyh = h - dy;
588
    }
589
    else
590
    {
591
	desty = y;
592
	sourcey = - dy;
593
	copyh = h + dy;
594
    }
595
    if (dx > 0)
596
    {
597
	(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
598
			       w - dx, sourcey, dx, copyh, x + w, desty);
599
    }
600
    else if (dx < 0)
601
    {
602
	(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
603
			       0, sourcey, -dx, copyh, x + dx, desty);
604
    }
605
    if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
606
	return FALSE;
607
    pGC = pScreenPriv->pSaveGC;
608
    if (pSave->drawable.serialNumber != pGC->serialNumber)
609
	ValidateGC ((DrawablePtr) pSave, pGC);
610
    /*
611
     * move the bits that are still valid within the pixmap
612
     */
613
    if (dx >= 0)
614
    {
615
	sourcex = 0;
616
	destx = dx;
617
	copyw = w - dx;
618
    }
619
    else
620
    {
621
	destx = 0;
622
	sourcex = - dx;
623
	copyw = w + dx;
624
    }
625
    if (dy >= 0)
626
    {
627
	sourcey = 0;
628
	desty = dy;
629
	copyh = h - dy;
630
    }
631
    else
632
    {
633
	desty = 0;
634
	sourcey = -dy;
635
	copyh = h + dy;
636
    }
637
    (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pSave, pGC,
638
			   sourcex, sourcey, copyw, copyh, destx, desty);
639
    /*
640
     * copy the new bits from the screen into the remaining areas of the
641
     * pixmap
642
     */
643
    if (dy > 0)
644
    {
645
	(*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
646
			       x, y, w, dy, 0, 0);
647
    }
648
    else if (dy < 0)
649
    {
650
	(*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
651
			       x, y + h + dy, w, -dy, 0, h + dy);
652
    }
653
    if (dy >= 0)
654
    {
655
	desty = dy;
656
	sourcey = y + dy;
657
	copyh = h - dy;
658
    }
659
    else
660
    {
661
	desty = 0;
662
	sourcey = y;
663
	copyh = h + dy;
664
    }
665
    if (dx > 0)
666
    {
667
	(*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
668
			       x, sourcey, dx, copyh, 0, desty);
669
    }
670
    else if (dx < 0)
671
    {
672
	(*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
673
			       x + w + dx, sourcey, -dx, copyh, w + dx, desty);
674
    }
675
    return TRUE;
676
}
677
678
static Bool
679
rfbDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
680
    ScreenPtr	    pScreen;
681
    CursorPtr	    pCursor;
682
    int		    x, y, w, h, dx, dy;
683
    unsigned long   source, mask;
684
{
685
    rfbDCCursorPtr   pPriv;
686
    rfbDCScreenPtr   pScreenPriv;
687
    int		    status;
688
    WindowPtr	    pWin;
689
    GCPtr	    pGC;
690
    XID		    gcval = FALSE;
691
    PixmapPtr	    pTemp;
692
693
    pPriv = (rfbDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
694
    if (!pPriv)
695
    {
696
	pPriv = rfbDCRealize(pScreen, pCursor);
697
	if (!pPriv)
698
	    return FALSE;
699
    }
700
    pScreenPriv = (rfbDCScreenPtr) pScreen->devPrivates[rfbDCScreenIndex].ptr;
701
    pWin = WindowTable[pScreen->myNum];
702
    pTemp = pScreenPriv->pTemp;
703
    if (!pTemp ||
704
	pTemp->drawable.width != pScreenPriv->pSave->drawable.width ||
705
	pTemp->drawable.height != pScreenPriv->pSave->drawable.height)
706
    {
707
	if (pTemp)
708
	    (*pScreen->DestroyPixmap) (pTemp);
709
#ifdef ARGB_CURSOR
710
	if (pScreenPriv->pTempPicture)
711
	{
712
	    FreePicture (pScreenPriv->pTempPicture, 0);
713
	    pScreenPriv->pTempPicture = 0;
714
	}
715
#endif
716
	pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap)
717
	    (pScreen, w, h, pScreenPriv->pSave->drawable.depth);
718
	if (!pTemp)
719
	    return FALSE;
720
    }
721
    if (!pScreenPriv->pMoveGC)
722
    {
723
	pScreenPriv->pMoveGC = CreateGC ((DrawablePtr)pTemp,
724
	    GCGraphicsExposures, &gcval, &status);
725
	if (!pScreenPriv->pMoveGC)
726
	    return FALSE;
727
    }
728
    /*
729
     * copy the saved area to a temporary pixmap
730
     */
731
    pGC = pScreenPriv->pMoveGC;
732
    if (pGC->serialNumber != pTemp->drawable.serialNumber)
733
	ValidateGC ((DrawablePtr) pTemp, pGC);
734
    (*pGC->ops->CopyArea)((DrawablePtr)pScreenPriv->pSave,
735
			  (DrawablePtr)pTemp, pGC, 0, 0, w, h, 0, 0);
736
    
737
    /*
738
     * draw the cursor in the temporary pixmap
739
     */
740
#ifdef ARGB_CURSOR
741
    if (pPriv->pPicture)
742
    {
743
	if (!EnsurePicture(pScreenPriv->pTempPicture, &pTemp->drawable, pWin))
744
	    return FALSE;
745
	CompositePicture (PictOpOver,
746
			  pPriv->pPicture,
747
			  NULL,
748
			  pScreenPriv->pTempPicture,
749
			  0, 0, 0, 0, 
750
			  dx, dy, 
751
			  pCursor->bits->width,
752
			  pCursor->bits->height);
753
    }
754
    else
755
#endif
756
    {
757
	if (!pScreenPriv->pPixSourceGC)
758
	{
759
	    pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp,
760
		GCGraphicsExposures, &gcval, &status);
761
	    if (!pScreenPriv->pPixSourceGC)
762
		return FALSE;
763
	}
764
	if (!pScreenPriv->pPixMaskGC)
765
	{
766
	    pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp,
767
		GCGraphicsExposures, &gcval, &status);
768
	    if (!pScreenPriv->pPixMaskGC)
769
		return FALSE;
770
	}
771
	rfbDCPutBits ((DrawablePtr)pTemp, pPriv,
772
		     pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC,
773
		     dx, dy, pCursor->bits->width, pCursor->bits->height,
774
		     source, mask);
775
    }
776
777
    /*
778
     * copy the temporary pixmap onto the screen
779
     */
780
781
    if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
782
	return FALSE;
783
    pGC = pScreenPriv->pRestoreGC;
784
    if (pWin->drawable.serialNumber != pGC->serialNumber)
785
	ValidateGC ((DrawablePtr) pWin, pGC);
786
787
    (*pGC->ops->CopyArea) ((DrawablePtr) pTemp, (DrawablePtr) pWin,
788
			    pGC,
789
			    0, 0, w, h, x, y);
790
    return TRUE;
791
}
(-)xorg-server-1.4.orig/hw/vnc/dpmsstubs.c (+52 lines)
Line 0 Link Here
1
/* $Xorg: dpmsstubs.c,v 1.3 2000/08/17 19:47:56 cpqbld Exp $ */
2
/*****************************************************************
3
4
Copyright (c) 1996 Digital Equipment Corporation, Maynard, Massachusetts.
5
6
Permission is hereby granted, free of charge, to any person obtaining a copy
7
of this software and associated documentation files (the "Software"), to deal
8
in the Software without restriction, including without limitation the rights
9
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
copies of the Software.
11
12
The above copyright notice and this permission notice shall be included in
13
all copies or substantial portions of the Software.
14
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 
19
BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 
20
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 
21
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23
Except as contained in this notice, the name of Digital Equipment Corporation 
24
shall not be used in advertising or otherwise to promote the sale, use or other
25
dealings in this Software without prior written authorization from Digital 
26
Equipment Corporation.
27
28
******************************************************************/
29
/* $XFree86: xc/programs/Xserver/Xext/dpmsstubs.c,v 3.3 1999/12/16 02:26:23 robin Exp $ */
30
31
#ifdef HAVE_DIX_CONFIG_H
32
#include <dix-config.h>
33
#endif
34
35
#include "rfb.h"
36
37
#define FALSE 0
38
39
Bool DPMSSupported(void)
40
{
41
    return FALSE;
42
}
43
44
int DPSMGet(int *level)
45
{
46
    return -1;
47
}
48
49
void DPMSSet(int level)
50
{
51
52
}
(-)xorg-server-1.4.orig/hw/vnc/draw.c (+2020 lines)
Line 0 Link Here
1
/*
2
 * draw.c - drawing routines for the RFB X server.  This is a set of
3
 * wrappers around the standard MI/MFB/CFB drawing routines which work out
4
 * to a fair approximation the region of the screen being modified by the
5
 * drawing.  If the RFB client is ready then the modified region of the screen
6
 * is sent to the client, otherwise the modified region will simply grow with
7
 * each drawing request until the client is ready.
8
 *
9
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
10
 */
11
12
/*
13
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
14
 *
15
 *  This is free software; you can redistribute it and/or modify
16
 *  it under the terms of the GNU General Public License as published by
17
 *  the Free Software Foundation; either version 2 of the License, or
18
 *  (at your option) any later version.
19
 *
20
 *  This software is distributed in the hope that it will be useful,
21
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 *  GNU General Public License for more details.
24
 *
25
 *  You should have received a copy of the GNU General Public License
26
 *  along with this software; if not, write to the Free Software
27
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
28
 *  USA.
29
 */
30
31
/*
32
33
Copyright (c) 1989  X Consortium
34
35
Permission is hereby granted, free of charge, to any person obtaining a copy
36
of this software and associated documentation files (the "Software"), to deal
37
in the Software without restriction, including without limitation the rights
38
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39
copies of the Software, and to permit persons to whom the Software is
40
furnished to do so, subject to the following conditions:
41
42
The above copyright notice and this permission notice shall be included in
43
all copies or substantial portions of the Software.
44
45
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
48
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
49
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
50
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
51
52
Except as contained in this notice, the name of the X Consortium shall not be
53
used in advertising or otherwise to promote the sale, use or other dealings
54
in this Software without prior written authorization from the X Consortium.
55
*/
56
#ifdef HAVE_DIX_CONFIG_H
57
#include <dix-config.h>
58
#endif
59
60
#include "rfb.h"
61
62
int rfbDeferUpdateTime = 40; /* ms */
63
64
65
/****************************************************************************/
66
/*
67
 * Macro definitions
68
 */
69
/****************************************************************************/
70
71
#define TRC(x) /* (rfbLog x) */
72
73
/* ADD_TO_MODIFIED_REGION adds the given region to the modified region for each
74
   client */
75
76
#define ADD_TO_MODIFIED_REGION(pScreen,reg)				      \
77
  {									      \
78
      rfbClientPtr cl;							      \
79
      for (cl = rfbClientHead; cl; cl = cl->next) {			      \
80
	  REGION_UNION((pScreen),&cl->modifiedRegion,&cl->modifiedRegion,reg);\
81
      }									      \
82
  }
83
84
/* SCHEDULE_FB_UPDATE is used at the end of each drawing routine to schedule an
85
   update to be sent to each client if there is one pending and the client is
86
   ready for it.  */
87
88
#define SCHEDULE_FB_UPDATE(pScreen,pVNC)				\
89
  if (!pVNC->dontSendFramebufferUpdate) {				\
90
      rfbClientPtr cl, nextCl;						\
91
      for (cl = rfbClientHead; cl; cl = nextCl) {			\
92
	  nextCl = cl->next;						\
93
	  if (!cl->deferredUpdateScheduled && FB_UPDATE_PENDING(cl) && 	\
94
	      REGION_NOTEMPTY(pScreen,&cl->requestedRegion)) 		\
95
	  {								\
96
	      rfbScheduleDeferredUpdate(pScreen, cl);			\
97
	  }								\
98
      }									\
99
  }
100
101
/* function prototypes */
102
103
static void rfbScheduleDeferredUpdate(ScreenPtr pScreen, rfbClientPtr cl);
104
static void rfbCopyRegion(ScreenPtr pScreen, rfbClientPtr cl,
105
			  RegionPtr src, RegionPtr dst, int dx, int dy);
106
#ifdef DEBUG
107
static void PrintRegion(ScreenPtr pScreen, RegionPtr reg);
108
#endif
109
110
/* GC funcs */
111
112
static void rfbValidateGC(GCPtr, unsigned long /*changes*/, DrawablePtr);
113
static void rfbChangeGC(GCPtr, unsigned long /*mask*/);
114
static void rfbCopyGC(GCPtr /*src*/, unsigned long /*mask*/, GCPtr /*dst*/);
115
static void rfbDestroyGC(GCPtr);
116
static void rfbChangeClip(GCPtr, int /*type*/, pointer /*pValue*/,
117
			  int /*nrects*/);
118
static void rfbDestroyClip(GCPtr);
119
static void rfbCopyClip(GCPtr /*dst*/, GCPtr /*src*/);
120
121
/* GC ops */
122
123
static void rfbFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit, DDXPointPtr pptInit, int *pwidthInit, int fSorted);
124
static void rfbSetSpans(DrawablePtr 		pDrawable, 
125
	    		GCPtr			pGC, 
126
	    		char			*psrc, 
127
	    		register DDXPointPtr	ppt, 
128
	    		int			*pwidth, 
129
	    		int			nspans, 
130
	    		int			fSorted);
131
static void rfbPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits);
132
static RegionPtr rfbCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty);
133
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);
134
static void rfbPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, xPoint *pts);
135
static void rfbPolylines (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppts);
136
static void rfbPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *segs);
137
static void rfbPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects);
138
static void rfbPolyArc(DrawablePtr pDrawable, register GCPtr pGC, int narcs, xArc *arcs);
139
static void rfbFillPolygon(register DrawablePtr pDrawable, register GCPtr pGC, int shape, int mode, int count, DDXPointPtr pts);
140
static void rfbPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects);
141
static void rfbPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *arcs);
142
static int rfbPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars);
143
static int rfbPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars);
144
static void rfbImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars);
145
static void rfbImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars);
146
static void rfbImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase);
147
static void rfbPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase);
148
static void rfbPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, int w, int h, int x, int y);
149
150
151
static GCFuncs rfbGCFuncs = {
152
    rfbValidateGC,
153
    rfbChangeGC,
154
    rfbCopyGC,
155
    rfbDestroyGC,
156
    rfbChangeClip,
157
    rfbDestroyClip,
158
    rfbCopyClip,
159
};
160
161
162
static GCOps rfbGCOps = {
163
    rfbFillSpans,	rfbSetSpans,	rfbPutImage,	
164
    rfbCopyArea,	rfbCopyPlane,	rfbPolyPoint,
165
    rfbPolylines,	rfbPolySegment,	rfbPolyRectangle,
166
    rfbPolyArc,		rfbFillPolygon,	rfbPolyFillRect,
167
    rfbPolyFillArc,	rfbPolyText8,	rfbPolyText16,
168
    rfbImageText8,	rfbImageText16,	rfbImageGlyphBlt,
169
    rfbPolyGlyphBlt,	rfbPushPixels
170
};
171
172
173
174
/****************************************************************************/
175
/*
176
 * Screen functions wrapper stuff
177
 */
178
/****************************************************************************/
179
180
#define SCREEN_PROLOGUE(scrn, field)		\
181
    ScreenPtr pScreen = scrn;			\
182
    VNCSCREENPTR(pScreen); 		\
183
    pScreen->field = pVNC->field;
184
185
#define SCREEN_EPILOGUE(field, wrapper) \
186
    pScreen->field = wrapper;
187
188
189
/*
190
 * CloseScreen wrapper -- unwrap everything, free the private data
191
 * and call the wrapped CloseScreen function.
192
 */
193
194
Bool
195
rfbCloseScreen (int i, ScreenPtr pScreen)
196
{
197
    VNCSCREENPTR(pScreen);
198
#if XFREE86VNC
199
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
200
#endif
201
    int sock;
202
203
    for (sock = 0; sock <= pVNC->maxFd; sock++) {
204
	if (FD_ISSET(sock, &pVNC->allFds))
205
	    if (sock != pVNC->rfbListenSock && sock != pVNC->httpListenSock) {
206
	    	rfbCloseSock(pScreen, sock);
207
	    }
208
    }
209
210
    if (pVNC->rfbListenSock > 0)
211
    	if (close(pVNC->rfbListenSock))
212
		ErrorF("Close of port %d failed\n",pVNC->rfbPort);
213
214
    if (pVNC->httpListenSock > 0)
215
    	if (close(pVNC->httpListenSock))
216
		ErrorF("Close of port %d failed\n",pVNC->httpPort);
217
218
    pScreen->CloseScreen = pVNC->CloseScreen;
219
    pScreen->CreateGC = pVNC->CreateGC;
220
    pScreen->PaintWindowBackground = pVNC->PaintWindowBackground;
221
    pScreen->PaintWindowBorder = pVNC->PaintWindowBorder;
222
    pScreen->CopyWindow = pVNC->CopyWindow;
223
    pScreen->ClearToBackground = pVNC->ClearToBackground;
224
    pScreen->RestoreAreas = pVNC->RestoreAreas;
225
    pScreen->WakeupHandler = pVNC->WakeupHandler;
226
227
#if XFREE86VNC
228
    pScreen->InstallColormap = pVNC->InstallColormap;
229
    pScreen->UninstallColormap = pVNC->UninstallColormap;
230
    pScreen->ListInstalledColormaps = pVNC->ListInstalledColormaps;
231
    pScreen->StoreColors = pVNC->StoreColors;
232
    pScrn->EnableDisableFBAccess = pVNC->EnableDisableFBAccess;
233
234
    xfree(pVNC);
235
#endif
236
237
    TRC((stderr,"Unwrapped screen functions\n"));
238
239
    return (*pScreen->CloseScreen) (i, pScreen);
240
}
241
242
#if XFREE86VNC
243
void
244
rfbEnableDisableFBAccess (int index, Bool enable)
245
{
246
    ScrnInfoPtr pScrn = xf86Screens[index];
247
    VNCSCREENPTR(pScrn->pScreen);
248
249
    /* 
250
     * Blank the screen for security while inputs are disabled.
251
     * When VT switching is fixed, we might be able to allow
252
     * control even when switched away. 
253
     */
254
    if (!enable) {
255
	WindowPtr pWin = WindowTable[index];
256
    	ScreenPtr pScreen = pWin->drawable.pScreen;
257
    	GCPtr pGC;
258
    	xRectangle rect;
259
260
    	rect.x = 0;
261
    	rect.y = 0;
262
    	rect.width = pScrn->virtualX;
263
    	rect.height = pScrn->virtualY;
264
265
    	if (!(pGC = GetScratchGC(pScreen->rootDepth, pScreen))) {
266
    	    ErrorF("Couldn't blank screen");
267
    	} else {
268
	    CARD32 attributes[2];
269
	    attributes[0] = pScreen->whitePixel;
270
	    attributes[1] = pScreen->blackPixel;
271
	    (void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
272
273
	    ValidateGC((DrawablePtr)pWin, pGC);
274
275
  	    (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, 1, &rect);
276
277
   	    FreeScratchGC(pGC);
278
    	
279
	    /* Flush pending packets */
280
	    rfbCheckFds(pScreen);
281
	    httpCheckFds(pScreen);
282
    	}
283
    }
284
285
    pScrn->EnableDisableFBAccess = pVNC->EnableDisableFBAccess;
286
    (*pScrn->EnableDisableFBAccess)(index, enable);
287
    pScrn->EnableDisableFBAccess = rfbEnableDisableFBAccess;
288
}
289
#endif
290
291
/*
292
 * CreateGC - wrap the GC funcs (the GC ops will be wrapped when the GC
293
 * func "ValidateGC" is called).
294
 */
295
296
Bool
297
rfbCreateGC (GCPtr pGC)
298
{
299
    Bool ret;
300
    rfbGCPtr pGCPriv;
301
302
    SCREEN_PROLOGUE(pGC->pScreen,CreateGC);
303
304
    pGCPriv = (rfbGCPtr)pGC->devPrivates[rfbGCIndex].ptr;
305
306
    ret = (*pScreen->CreateGC) (pGC);
307
308
    TRC((stderr,"rfbCreateGC called\n"));
309
310
    pGCPriv->wrapOps = NULL;
311
    pGCPriv->wrapFuncs = pGC->funcs;
312
    pGC->funcs = &rfbGCFuncs;
313
314
    SCREEN_EPILOGUE(CreateGC,rfbCreateGC);
315
316
    return ret;
317
}
318
319
/*
320
 * PaintWindowBackground - the region being modified is just the given region.
321
 */
322
323
void
324
rfbPaintWindowBackground (WindowPtr pWin, RegionPtr pRegion, int what)
325
{
326
    SCREEN_PROLOGUE(pWin->drawable.pScreen,PaintWindowBackground);
327
328
    TRC((stderr,"rfbPaintWindowBackground called\n"));
329
330
    ADD_TO_MODIFIED_REGION(pScreen,pRegion);
331
332
    (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
333
334
    SCHEDULE_FB_UPDATE(pScreen, pVNC);
335
336
    SCREEN_EPILOGUE(PaintWindowBackground,rfbPaintWindowBackground);
337
}
338
339
/*
340
 * PaintWindowBorder - the region being modified is just the given region.
341
 */
342
343
void
344
rfbPaintWindowBorder (WindowPtr pWin, RegionPtr pRegion, int what)
345
{
346
    SCREEN_PROLOGUE(pWin->drawable.pScreen,PaintWindowBorder);
347
348
    TRC((stderr,"rfbPaintWindowBorder called\n"));
349
350
    ADD_TO_MODIFIED_REGION(pScreen,pRegion);
351
352
    (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
353
354
    SCHEDULE_FB_UPDATE(pScreen, pVNC);
355
356
    SCREEN_EPILOGUE(PaintWindowBorder,rfbPaintWindowBorder);
357
}
358
359
#ifdef CHROMIUM
360
Bool
361
rfbRealizeWindow(WindowPtr pWin)
362
{
363
    CRWindowTable *wt = NULL, *nextWt = NULL;
364
    Bool ret;
365
    SCREEN_PROLOGUE(pWin->drawable.pScreen,RealizeWindow);
366
367
    for (wt = windowTable; wt; wt = nextWt) {
368
   	 nextWt = wt->next;
369
	 if (wt->XwinId == pWin->drawable.id) {
370
	    rfbSendChromiumWindowShow(wt->CRwinId, 1);
371
	 }
372
    }
373
374
    ret = (*pScreen->RealizeWindow)(pWin);
375
376
    SCREEN_EPILOGUE(RealizeWindow,rfbRealizeWindow);
377
378
    return ret;
379
}
380
381
Bool
382
rfbUnrealizeWindow(WindowPtr pWin)
383
{
384
    CRWindowTable *wt = NULL, *nextWt = NULL;
385
    Bool ret;
386
    SCREEN_PROLOGUE(pWin->drawable.pScreen,UnrealizeWindow);
387
388
    for (wt = windowTable; wt; wt = nextWt) {
389
   	 nextWt = wt->next;
390
	 if (wt->XwinId == pWin->drawable.id) {
391
	    rfbSendChromiumWindowShow(wt->CRwinId, 0);
392
	 }
393
    }
394
395
    ret = (*pScreen->UnrealizeWindow)(pWin);
396
397
    SCREEN_EPILOGUE(UnrealizeWindow,rfbUnrealizeWindow);
398
399
    return ret;
400
}
401
402
Bool
403
rfbDestroyWindow(WindowPtr pWin)
404
{
405
    CRWindowTable *wt = NULL, *nextWt = NULL, *prevWt = NULL;
406
    Bool ret;
407
    SCREEN_PROLOGUE(pWin->drawable.pScreen,DestroyWindow);
408
409
    /* loop over monitored windows */
410
    for (wt = windowTable; wt; wt = nextWt) {
411
	nextWt = wt->next;
412
	if (wt->XwinId == pWin->drawable.id) {
413
	    rfbSendChromiumWindowDestroy(wt->CRwinId);
414
	    /* also remove from list */
415
	    if (prevWt)
416
	        prevWt->next = wt->next;
417
	    else
418
	        windowTable = wt->next;
419
            xfree(wt);
420
        }
421
        else {
422
            prevWt = wt;
423
        }
424
    }
425
426
    ret = (*pScreen->DestroyWindow)(pWin);
427
428
    SCREEN_EPILOGUE(DestroyWindow,rfbDestroyWindow);
429
430
    return ret;
431
}
432
433
void
434
rfbResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, WindowPtr pSib)
435
{
436
    CRWindowTable *wt = NULL, *nextWt = NULL;
437
    SCREEN_PROLOGUE(pWin->drawable.pScreen,ResizeWindow);
438
439
    for (wt = windowTable; wt; wt = nextWt) {
440
   	 nextWt = wt->next;
441
	 if (wt->XwinId == pWin->drawable.id) {
442
	     rfbSendChromiumMoveResizeWindow(wt->CRwinId, pWin->drawable.x, pWin->drawable.y, w, h);
443
	 }
444
    }
445
446
    (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
447
448
    SCREEN_EPILOGUE(ResizeWindow,rfbResizeWindow);
449
}
450
451
Bool
452
rfbPositionWindow(WindowPtr pWin, int x, int y)
453
{
454
    Bool ret;
455
    CRWindowTable *wt, *nextWt;
456
    SCREEN_PROLOGUE(pWin->drawable.pScreen,PositionWindow);
457
458
    for (wt = windowTable; wt; wt = nextWt) {
459
   	 nextWt = wt->next;
460
	 if (wt->XwinId == pWin->drawable.id) {
461
	     rfbSendChromiumMoveResizeWindow(wt->CRwinId, x, y, pWin->drawable.width, pWin->drawable.height);
462
	 }
463
    }
464
465
    ret = (*pScreen->PositionWindow)(pWin, x, y);
466
467
    SCREEN_EPILOGUE(PositionWindow,rfbPositionWindow);
468
469
    return ret;
470
}
471
472
void
473
rfbClipNotify(WindowPtr pWin, int x, int y)
474
{
475
    CRWindowTable *wt, *nextWt;
476
    SCREEN_PROLOGUE(pWin->drawable.pScreen,ClipNotify);
477
478
    for (wt = windowTable; wt; wt = nextWt) {
479
   	 nextWt = wt->next;
480
	 if (wt->XwinId == pWin->drawable.id) {
481
	    int numClipRects = REGION_NUM_RECTS(&pWin->clipList);
482
	    BoxPtr pClipRects = REGION_RECTS(&pWin->clipList);
483
484
	    /* Possible optimization - has the cliplist really? changed */
485
486
	    rfbSendChromiumClipList(wt->CRwinId, pClipRects, numClipRects);
487
	 }
488
    }
489
490
    if (*pScreen->ClipNotify) 
491
    	(*pScreen->ClipNotify)(pWin, x, y);
492
493
    SCREEN_EPILOGUE(ClipNotify,rfbClipNotify);
494
}
495
#endif /* CHROMIUM */
496
497
/*
498
 * CopyWindow - the region being modified is the translation of the old
499
 * region, clipped to the border clip region of the window.  Note that any
500
 * parts of the window which have become newly-visible will not be affected by
501
 * this call - a separate PaintWindowBackground/Border will be called to do
502
 * that.  If the client will accept CopyRect messages then use rfbCopyRegion to
503
 * optimise the pending screen changes into a single "copy region" plus the
504
 * ordinary modified region.
505
 */
506
507
void
508
rfbCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion)
509
{
510
    rfbClientPtr cl;
511
    RegionRec srcRegion, dstRegion;
512
    SCREEN_PROLOGUE(pWin->drawable.pScreen,CopyWindow);
513
514
    TRC((stderr,"rfbCopyWindow called\n"));
515
516
    REGION_NULL(pScreen,&dstRegion);
517
    REGION_COPY(pScreen,&dstRegion,pOldRegion);
518
    REGION_TRANSLATE(pWin->drawable.pScreen, &dstRegion,
519
		     pWin->drawable.x - ptOldOrg.x,
520
		     pWin->drawable.y - ptOldOrg.y);
521
    REGION_INTERSECT(pWin->drawable.pScreen, &dstRegion, &dstRegion,
522
		     &pWin->borderClip);
523
524
    for (cl = rfbClientHead; cl; cl = cl->next) {
525
	if (cl->useCopyRect) {
526
	    REGION_NULL(pScreen,&srcRegion);
527
	    REGION_COPY(pScreen,&srcRegion,pOldRegion);
528
529
	    rfbCopyRegion(pScreen, cl, &srcRegion, &dstRegion,
530
			  pWin->drawable.x - ptOldOrg.x,
531
			  pWin->drawable.y - ptOldOrg.y);
532
533
	    REGION_UNINIT(pScreen, &srcRegion);
534
535
	} else {
536
537
	    REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
538
			 &dstRegion);
539
	}
540
    }
541
542
    REGION_UNINIT(pScreen, &dstRegion);
543
544
    (*pScreen->CopyWindow) (pWin, ptOldOrg, pOldRegion);
545
546
    SCHEDULE_FB_UPDATE(pScreen, pVNC);
547
548
    SCREEN_EPILOGUE(CopyWindow,rfbCopyWindow);
549
}
550
551
/*
552
 * ClearToBackground - when generateExposures is false, the region being
553
 * modified is the given rectangle (clipped to the "window clip region").
554
 */
555
556
void
557
rfbClearToBackground (WindowPtr pWin, int x, int y, int w, int h, 
558
		      Bool generateExposures)
559
{
560
    RegionRec tmpRegion;
561
    BoxRec box;
562
    SCREEN_PROLOGUE(pWin->drawable.pScreen,ClearToBackground);
563
564
    TRC((stderr,"rfbClearToBackground called\n"));
565
566
    if (!generateExposures) {
567
	box.x1 = x + pWin->drawable.x;
568
	box.y1 = y + pWin->drawable.y;
569
	box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width);
570
	box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height);
571
572
	SAFE_REGION_INIT(pScreen, &tmpRegion, &box, 0);
573
574
	REGION_INTERSECT(pScreen, &tmpRegion, &tmpRegion, &pWin->clipList);
575
576
	ADD_TO_MODIFIED_REGION(pScreen, &tmpRegion);
577
578
	REGION_UNINIT(pScreen, &tmpRegion);
579
    }
580
581
    (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
582
583
    if (!generateExposures) {
584
	SCHEDULE_FB_UPDATE(pScreen, pVNC);
585
    }
586
587
    SCREEN_EPILOGUE(ClearToBackground,rfbClearToBackground);
588
}
589
590
/*
591
 * RestoreAreas - just be safe here - the region being modified is the whole
592
 * exposed region.
593
 */
594
595
RegionPtr
596
rfbRestoreAreas (WindowPtr pWin, RegionPtr prgnExposed)
597
{
598
    RegionPtr result;
599
    SCREEN_PROLOGUE(pWin->drawable.pScreen,RestoreAreas);
600
601
    TRC((stderr,"rfbRestoreAreas called\n"));
602
603
    ADD_TO_MODIFIED_REGION(pScreen, prgnExposed);
604
605
    result = (*pScreen->RestoreAreas) (pWin, prgnExposed);
606
607
    SCHEDULE_FB_UPDATE(pScreen, pVNC);
608
609
    SCREEN_EPILOGUE(RestoreAreas,rfbRestoreAreas);
610
611
    return result;
612
}
613
614
615
616
/****************************************************************************/
617
/*
618
 * GC funcs wrapper stuff
619
 *
620
 * We only really want to wrap the GC ops, but to do this we need to wrap
621
 * ValidateGC and so all the other GC funcs must be wrapped as well.
622
 */
623
/****************************************************************************/
624
625
#define GC_FUNC_PROLOGUE(pGC)						\
626
    rfbGCPtr pGCPriv = (rfbGCPtr) (pGC)->devPrivates[rfbGCIndex].ptr;	\
627
    (pGC)->funcs = pGCPriv->wrapFuncs;					\
628
    if (pGCPriv->wrapOps)						\
629
	(pGC)->ops = pGCPriv->wrapOps;
630
631
#define GC_FUNC_EPILOGUE(pGC)		\
632
    pGCPriv->wrapFuncs = (pGC)->funcs;	\
633
    (pGC)->funcs = &rfbGCFuncs;		\
634
    if (pGCPriv->wrapOps) {		\
635
	pGCPriv->wrapOps = (pGC)->ops;	\
636
	(pGC)->ops = &rfbGCOps;		\
637
    }
638
639
640
/*
641
 * ValidateGC - call the wrapped ValidateGC, then wrap the resulting GC ops if
642
 * the drawing will be to a viewable window.
643
 */
644
645
static void
646
rfbValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
647
{
648
    GC_FUNC_PROLOGUE(pGC);
649
650
    TRC((stderr,"rfbValidateGC called\n"));
651
652
    (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
653
    
654
    pGCPriv->wrapOps = NULL;
655
    if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr)pDrawable)->viewable)
656
    {
657
	WindowPtr   pWin = (WindowPtr) pDrawable;
658
	RegionPtr   pRegion = &pWin->clipList;
659
660
	if (pGC->subWindowMode == IncludeInferiors)
661
	    pRegion = &pWin->borderClip;
662
	if (REGION_NOTEMPTY(pDrawable->pScreen, pRegion)) {
663
	    pGCPriv->wrapOps = pGC->ops;
664
	    TRC((stderr,"rfbValidateGC: wrapped GC ops\n"));
665
	}
666
    }
667
668
    GC_FUNC_EPILOGUE(pGC);
669
}
670
671
/*
672
 * All other GC funcs simply unwrap the GC funcs and ops, call the wrapped
673
 * function and then rewrap the funcs and ops.
674
 */
675
676
static void
677
rfbChangeGC (pGC, mask)
678
    GCPtr	    pGC;
679
    unsigned long   mask;
680
{
681
    GC_FUNC_PROLOGUE(pGC);
682
    (*pGC->funcs->ChangeGC) (pGC, mask);
683
    GC_FUNC_EPILOGUE(pGC);
684
}
685
686
static void
687
rfbCopyGC (pGCSrc, mask, pGCDst)
688
    GCPtr	    pGCSrc, pGCDst;
689
    unsigned long   mask;
690
{
691
    GC_FUNC_PROLOGUE(pGCDst);
692
    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
693
    GC_FUNC_EPILOGUE(pGCDst);
694
}
695
696
static void
697
rfbDestroyGC (pGC)
698
    GCPtr   pGC;
699
{
700
    GC_FUNC_PROLOGUE(pGC);
701
    (*pGC->funcs->DestroyGC) (pGC);
702
    GC_FUNC_EPILOGUE(pGC);
703
}
704
705
static void
706
rfbChangeClip (pGC, type, pvalue, nrects)
707
    GCPtr   pGC;
708
    int		type;
709
    pointer	pvalue;
710
    int		nrects;
711
{
712
    GC_FUNC_PROLOGUE(pGC);
713
    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
714
    GC_FUNC_EPILOGUE(pGC);
715
}
716
717
static void
718
rfbDestroyClip(pGC)
719
    GCPtr	pGC;
720
{
721
    GC_FUNC_PROLOGUE(pGC);
722
    (* pGC->funcs->DestroyClip)(pGC);
723
    GC_FUNC_EPILOGUE(pGC);
724
}
725
726
static void
727
rfbCopyClip(pgcDst, pgcSrc)
728
    GCPtr pgcDst, pgcSrc;
729
{
730
    GC_FUNC_PROLOGUE(pgcDst);
731
    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
732
    GC_FUNC_EPILOGUE(pgcDst);
733
}
734
735
736
/****************************************************************************/
737
/*
738
 * GC ops wrapper stuff
739
 *
740
 * Note that these routines will only have been wrapped for drawing to
741
 * viewable windows so we don't need to check each time that the drawable
742
 * is a viewable window.
743
 */
744
/****************************************************************************/
745
746
#define GC_OP_PROLOGUE(pDrawable,pGC) \
747
    ScreenPtr pScreen = pGC->pScreen;			\
748
    VNCSCREENPTR(pScreen);			\
749
    rfbGCPtr pGCPrivate = (rfbGCPtr) (pGC)->devPrivates[rfbGCIndex].ptr; \
750
    GCFuncs *oldFuncs = pGC->funcs; \
751
    (void) pScreen; /* silence compiler */ \
752
    (pGC)->funcs = pGCPrivate->wrapFuncs; \
753
    (pGC)->ops = pGCPrivate->wrapOps;
754
755
#define GC_OP_EPILOGUE(pGC) \
756
    pGCPrivate->wrapOps = (pGC)->ops; \
757
    (pGC)->funcs = oldFuncs; \
758
    (pGC)->ops = &rfbGCOps;
759
760
761
/*
762
 * FillSpans - being very safe - the region being modified is the border clip
763
 * region of the window.
764
 */
765
766
static void
767
rfbFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
768
    DrawablePtr pDrawable;
769
    GCPtr	pGC;
770
    int		nInit;			/* number of spans to fill */
771
    DDXPointPtr pptInit;		/* pointer to list of start points */
772
    int		*pwidthInit;		/* pointer to list of n widths */
773
    int 	fSorted;
774
{
775
    GC_OP_PROLOGUE(pDrawable,pGC);
776
777
    TRC((stderr,"rfbFillSpans called\n"));
778
779
    ADD_TO_MODIFIED_REGION(pDrawable->pScreen,
780
			   &((WindowPtr)pDrawable)->borderClip);
781
782
    (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit,pwidthInit,fSorted);
783
784
    SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
785
786
    GC_OP_EPILOGUE(pGC);
787
}
788
789
/*
790
 * SetSpans - being very safe - the region being modified is the border clip
791
 * region of the window.
792
 */
793
794
static void
795
rfbSetSpans(DrawablePtr 		pDrawable, 
796
	    GCPtr			pGC, 
797
	    char			*psrc, 
798
	    register DDXPointPtr	ppt, 
799
	    int				*pwidth, 
800
	    int				nspans, 
801
	    int				fSorted)
802
{
803
    GC_OP_PROLOGUE(pDrawable,pGC);
804
805
    TRC((stderr,"rfbSetSpans called\n"));
806
807
    ADD_TO_MODIFIED_REGION(pDrawable->pScreen,
808
			   &((WindowPtr)pDrawable)->borderClip);
809
810
    (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
811
812
    SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
813
814
    GC_OP_EPILOGUE(pGC);
815
}
816
817
/*
818
 * PutImage - the region being modified is the rectangle of the
819
 * PutImage (clipped to the window clip region).
820
 */
821
822
static void
823
rfbPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits)
824
{
825
    RegionRec tmpRegion;
826
    BoxRec box;
827
    GC_OP_PROLOGUE(pDrawable, pGC);
828
829
    TRC((stderr,"rfbPutImage called\n"));
830
831
    box.x1 = x + pDrawable->x;
832
    box.y1 = y + pDrawable->y;
833
    box.x2 = box.x1 + w;
834
    box.y2 = box.y1 + h;
835
836
    SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
837
838
    REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
839
		     					pGC->pCompositeClip);
840
841
    ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
842
843
    REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
844
845
    (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h,
846
			   leftPad, format, pBits);
847
848
    SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
849
850
    GC_OP_EPILOGUE(pGC);
851
}
852
853
/*
854
 * CopyArea - the region being modified is the destination rectangle (clipped
855
 * to the window clip region).
856
 * If the client will accept CopyRect messages then use rfbCopyRegion
857
 * to optimise the pending screen changes into a single "copy region" plus
858
 * the ordinary modified region.
859
 */
860
861
static RegionPtr
862
rfbCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty)
863
{
864
    rfbClientPtr cl;
865
    RegionPtr rgn;
866
    RegionRec srcRegion, dstRegion;
867
    BoxRec box;
868
    GC_OP_PROLOGUE(pDst, pGC);
869
870
    TRC((stderr,"rfbCopyArea called\n"));
871
872
    box.x1 = dstx + pDst->x;
873
    box.y1 = dsty + pDst->y;
874
    box.x2 = box.x1 + w;
875
    box.y2 = box.y1 + h;
876
877
    SAFE_REGION_INIT(pDst->pScreen, &dstRegion, &box, 0);
878
    REGION_INTERSECT(pDst->pScreen, &dstRegion, &dstRegion,
879
		     					pGC->pCompositeClip);
880
881
    if ((pSrc->type == DRAWABLE_WINDOW) && (pSrc->pScreen == pDst->pScreen)) {
882
	box.x1 = srcx + pSrc->x;
883
	box.y1 = srcy + pSrc->y;
884
	box.x2 = box.x1 + w;
885
	box.y2 = box.y1 + h;
886
887
	for (cl = rfbClientHead; cl; cl = cl->next) {
888
	    if (cl->useCopyRect) {
889
		SAFE_REGION_INIT(pSrc->pScreen, &srcRegion, &box, 0);
890
		REGION_INTERSECT(pSrc->pScreen, &srcRegion, &srcRegion,
891
				 &((WindowPtr)pSrc)->clipList);
892
893
		rfbCopyRegion(pSrc->pScreen, cl, &srcRegion, &dstRegion,
894
			      dstx + pDst->x - srcx - pSrc->x,
895
			      dsty + pDst->y - srcy - pSrc->y);
896
897
		REGION_UNINIT(pSrc->pScreen, &srcRegion);
898
899
	    } else {
900
901
		REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
902
			     &dstRegion);
903
	    }
904
	}
905
906
    } else {
907
908
	ADD_TO_MODIFIED_REGION(pDst->pScreen, &dstRegion);
909
    }
910
911
    REGION_UNINIT(pDst->pScreen, &dstRegion);
912
913
    rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h,
914
				 dstx, dsty);
915
916
    SCHEDULE_FB_UPDATE(pDst->pScreen, pVNC);
917
918
    GC_OP_EPILOGUE(pGC);
919
920
    return rgn;
921
}
922
923
924
/*
925
 * CopyPlane - the region being modified is the destination rectangle (clipped
926
 * to the window clip region).
927
 */
928
929
static RegionPtr
930
rfbCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, register GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long plane)
931
{
932
    RegionPtr rgn;
933
    RegionRec tmpRegion;
934
    BoxRec box;
935
    GC_OP_PROLOGUE(pDst, pGC);
936
937
    TRC((stderr,"rfbCopyPlane called\n"));
938
939
    box.x1 = dstx + pDst->x;
940
    box.y1 = dsty + pDst->y;
941
    box.x2 = box.x1 + w;
942
    box.y2 = box.y1 + h;
943
944
    SAFE_REGION_INIT(pDst->pScreen, &tmpRegion, &box, 0);
945
946
    REGION_INTERSECT(pDst->pScreen, &tmpRegion, &tmpRegion,
947
		     					pGC->pCompositeClip);
948
949
    ADD_TO_MODIFIED_REGION(pDst->pScreen, &tmpRegion);
950
951
    REGION_UNINIT(pDst->pScreen, &tmpRegion);
952
953
    rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
954
				  dstx, dsty, plane);
955
956
    SCHEDULE_FB_UPDATE(pDst->pScreen, pVNC);
957
958
    GC_OP_EPILOGUE(pGC);
959
960
    return rgn;
961
}
962
963
/*
964
 * PolyPoint - find the smallest rectangle which encloses the points drawn
965
 * (and clip).
966
 */
967
968
static void
969
rfbPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, xPoint *pts)
970
{
971
    int i;
972
    RegionRec tmpRegion;
973
    BoxRec box;
974
    GC_OP_PROLOGUE(pDrawable, pGC);
975
976
    TRC((stderr,"rfbPolyPoint called\n"));
977
978
    if (npt) {
979
	int minX = pts[0].x, maxX = pts[0].x;
980
	int minY = pts[0].y, maxY = pts[0].y;
981
982
	if (mode == CoordModePrevious)
983
	{
984
	    int x = pts[0].x, y = pts[0].y;
985
986
	    for (i = 1; i < npt; i++) {
987
		x += pts[i].x;
988
		y += pts[i].y;
989
		if (x < minX) minX = x;
990
		if (x > maxX) maxX = x;
991
		if (y < minY) minY = y;
992
		if (y > maxY) maxY = y;
993
	    }
994
	}
995
	else
996
	{
997
	    for (i = 1; i < npt; i++) {
998
		if (pts[i].x < minX) minX = pts[i].x;
999
		if (pts[i].x > maxX) maxX = pts[i].x;
1000
		if (pts[i].y < minY) minY = pts[i].y;
1001
		if (pts[i].y > maxY) maxY = pts[i].y;
1002
	    }
1003
	}
1004
1005
	box.x1 = minX + pDrawable->x;
1006
	box.y1 = minY + pDrawable->y;
1007
	box.x2 = maxX + 1 + pDrawable->x;
1008
	box.y2 = maxY + 1 + pDrawable->y;
1009
1010
	SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
1011
1012
	REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
1013
		     					pGC->pCompositeClip);
1014
1015
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
1016
1017
	REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
1018
    }
1019
1020
    (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts);
1021
1022
    if (npt) {
1023
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1024
    }
1025
1026
    GC_OP_EPILOGUE(pGC);
1027
}
1028
1029
/*
1030
 * PolyLines - take the union of bounding boxes around each line (and clip).
1031
 */
1032
1033
static void
1034
rfbPolylines (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppts)
1035
{
1036
    RegionPtr tmpRegion;
1037
    xRectangle *rects;
1038
    int i, extra, nlines, lw;
1039
    int x1, x2, y1, y2;
1040
    GC_OP_PROLOGUE(pDrawable, pGC);
1041
1042
    TRC((stderr,"rfbPolylines called\n"));
1043
1044
    if (npt) {
1045
	lw = pGC->lineWidth;
1046
	if (lw == 0)
1047
	    lw = 1;
1048
1049
	if (npt == 1)
1050
	{
1051
	    nlines = 1;
1052
	    rects = (xRectangle *)xalloc(sizeof(xRectangle));
1053
	    if (!rects) {
1054
		FatalError("rfbPolylines: xalloc failed\n");
1055
	    }
1056
1057
	    rects[0].x = ppts[0].x - lw + pDrawable->x; /* being safe here */
1058
	    rects[0].y = ppts[0].y - lw + pDrawable->y;
1059
	    rects[0].width = 2*lw;
1060
	    rects[0].height = 2*lw;
1061
	}
1062
	else
1063
	{
1064
	    nlines = npt - 1;
1065
	    rects = (xRectangle *)xalloc(nlines*sizeof(xRectangle));
1066
	    if (!rects) {
1067
		FatalError("rfbPolylines: xalloc failed\n");
1068
	    }
1069
1070
	    /*
1071
	     * mitered joins can project quite a way from
1072
	     * the line end; the 11 degree miter limit limits
1073
	     * this extension to lw / (2 * tan(11/2)), rounded up
1074
	     * and converted to int yields 6 * lw
1075
	     */
1076
1077
	    if (pGC->joinStyle == JoinMiter) {
1078
		extra = 6 * lw;
1079
	    } else {
1080
		extra = lw / 2;
1081
	    }
1082
1083
	    x1 = ppts[0].x + pDrawable->x;
1084
	    y1 = ppts[0].y + pDrawable->y;
1085
1086
	    for (i = 0; i < nlines; i++) {
1087
		if (mode == CoordModeOrigin) {
1088
		    x2 = pDrawable->x + ppts[i+1].x;
1089
		    y2 = pDrawable->y + ppts[i+1].y;
1090
		} else {
1091
		    x2 = x1 + ppts[i+1].x;
1092
		    y2 = y1 + ppts[i+1].y;
1093
		}
1094
1095
		if (x1 > x2) {
1096
		    rects[i].x = x2 - extra;
1097
		    rects[i].width = x1 - x2 + 1 + 2 * extra;
1098
		} else {
1099
		    rects[i].x = x1 - extra;
1100
		    rects[i].width = x2 - x1 + 1 + 2 * extra;
1101
		}
1102
1103
		if (y1 > y2) {
1104
		    rects[i].y = y2 - extra;
1105
		    rects[i].height = y1 - y2 + 1 + 2 * extra;
1106
		} else {
1107
		    rects[i].y = y1 - extra;
1108
		    rects[i].height = y2 - y1 + 1 + 2 * extra;
1109
		}
1110
1111
		x1 = x2;
1112
		y1 = y2;
1113
	    }
1114
	}
1115
	tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nlines, rects,CT_NONE);
1116
	REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
1117
		     					pGC->pCompositeClip);
1118
1119
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
1120
1121
	REGION_DESTROY(pDrawable->pScreen, tmpRegion);
1122
	xfree((char *)rects);
1123
    }
1124
1125
    (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppts);
1126
1127
    if (npt) {
1128
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1129
    }
1130
1131
    GC_OP_EPILOGUE(pGC);
1132
}
1133
1134
/*
1135
 * PolySegment - take the union of bounding boxes around each segment (and
1136
 * clip).
1137
 */
1138
1139
static void
1140
rfbPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *segs)
1141
{
1142
    RegionPtr tmpRegion;
1143
    xRectangle *rects;
1144
    int i, extra, lw;
1145
1146
    GC_OP_PROLOGUE(pDrawable, pGC);
1147
1148
    TRC((stderr,"rfbPolySegment called\n"));
1149
1150
    if (nseg) {
1151
	rects = (xRectangle *)xalloc(nseg*sizeof(xRectangle));
1152
	if (!rects) {
1153
	    FatalError("rfbPolySegment: xalloc failed\n");
1154
	}
1155
1156
	lw = pGC->lineWidth;
1157
	if (lw == 0)
1158
	    lw = 1;
1159
1160
	extra = lw / 2;
1161
1162
	for (i = 0; i < nseg; i++)
1163
	{
1164
	    if (segs[i].x1 > segs[i].x2) {
1165
		rects[i].x = segs[i].x2 - extra + pDrawable->x;
1166
		rects[i].width = segs[i].x1 - segs[i].x2 + 1 + 2 * extra;
1167
	    } else {
1168
		rects[i].x = segs[i].x1 - extra + pDrawable->x;
1169
		rects[i].width = segs[i].x2 - segs[i].x1 + 1 + 2 * extra;
1170
	    }
1171
1172
	    if (segs[i].y1 > segs[i].y2) {
1173
		rects[i].y = segs[i].y2 - extra + pDrawable->y;
1174
		rects[i].height = segs[i].y1 - segs[i].y2 + 1 + 2 * extra;
1175
	    } else {
1176
		rects[i].y = segs[i].y1 - extra + pDrawable->y;
1177
		rects[i].height = segs[i].y2 - segs[i].y1 + 1 + 2 * extra;
1178
	    }
1179
	}
1180
1181
	tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nseg, rects, CT_NONE);
1182
	REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
1183
		     					pGC->pCompositeClip);
1184
1185
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
1186
1187
	REGION_DESTROY(pDrawable->pScreen, tmpRegion);
1188
	xfree((char *)rects);
1189
    }
1190
1191
    (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, segs);
1192
1193
    if (nseg) {
1194
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1195
    }
1196
1197
    GC_OP_EPILOGUE(pGC);
1198
}
1199
1200
/*
1201
 * PolyRectangle (rectangle outlines) - take the union of bounding boxes
1202
 * around each line (and clip).
1203
 */
1204
1205
static void
1206
rfbPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects)
1207
{
1208
    int i, extra, lw;
1209
    RegionPtr tmpRegion;
1210
    xRectangle *regRects;
1211
    GC_OP_PROLOGUE(pDrawable, pGC);
1212
1213
    TRC((stderr,"rfbPolyRectangle called\n"));
1214
1215
    if (nrects) {
1216
	regRects = (xRectangle *)xalloc(nrects*4*sizeof(xRectangle));
1217
	if (!regRects) {
1218
	    FatalError("rfbPolyRectangle: xalloc failed\n");
1219
	}
1220
1221
	lw = pGC->lineWidth;
1222
	if (lw == 0)
1223
	    lw = 1;
1224
1225
	extra = lw / 2;
1226
1227
	for (i = 0; i < nrects; i++)
1228
	{
1229
	    regRects[i*4].x = rects[i].x - extra + pDrawable->x;
1230
	    regRects[i*4].y = rects[i].y - extra + pDrawable->y;
1231
	    regRects[i*4].width = rects[i].width + 1 + 2 * extra;
1232
	    regRects[i*4].height = 1 + 2 * extra;
1233
1234
	    regRects[i*4+1].x = rects[i].x - extra + pDrawable->x;
1235
	    regRects[i*4+1].y = rects[i].y - extra + pDrawable->y;
1236
	    regRects[i*4+1].width = 1 + 2 * extra;
1237
	    regRects[i*4+1].height = rects[i].height + 1 + 2 * extra;
1238
1239
	    regRects[i*4+2].x
1240
		= rects[i].x + rects[i].width - extra + pDrawable->x;
1241
	    regRects[i*4+2].y = rects[i].y - extra + pDrawable->y;
1242
	    regRects[i*4+2].width = 1 + 2 * extra;
1243
	    regRects[i*4+2].height = rects[i].height + 1 + 2 * extra;
1244
1245
	    regRects[i*4+3].x = rects[i].x - extra + pDrawable->x;
1246
	    regRects[i*4+3].y
1247
		= rects[i].y + rects[i].height - extra + pDrawable->y;
1248
	    regRects[i*4+3].width = rects[i].width + 1 + 2 * extra;
1249
	    regRects[i*4+3].height = 1 + 2 * extra;
1250
	}
1251
1252
	tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nrects*4,
1253
				    regRects, CT_NONE);
1254
	REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
1255
		     					pGC->pCompositeClip);
1256
1257
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
1258
1259
	REGION_DESTROY(pDrawable->pScreen, tmpRegion);
1260
	xfree((char *)regRects);
1261
    }
1262
1263
    (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, rects);
1264
1265
    if (nrects) {
1266
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1267
    }
1268
1269
    GC_OP_EPILOGUE(pGC);
1270
}
1271
1272
/*
1273
 * PolyArc - take the union of bounding boxes around each arc (and clip).
1274
 * Bounding boxes assume each is a full circle / ellipse.
1275
 */
1276
1277
static void
1278
rfbPolyArc(DrawablePtr pDrawable, register GCPtr pGC, int narcs, xArc *arcs)
1279
{
1280
    int i, extra, lw;
1281
    RegionPtr tmpRegion;
1282
    xRectangle *rects;
1283
    GC_OP_PROLOGUE(pDrawable, pGC);
1284
1285
    TRC((stderr,"rfbPolyArc called\n"));
1286
1287
    if (narcs) {
1288
	rects = (xRectangle *)xalloc(narcs*sizeof(xRectangle));
1289
	if (!rects) {
1290
	    FatalError("rfbPolyArc: xalloc failed\n");
1291
	}
1292
1293
	lw = pGC->lineWidth;
1294
	if (lw == 0)
1295
	    lw = 1;
1296
1297
	extra = lw / 2;
1298
1299
	for (i = 0; i < narcs; i++)
1300
	{
1301
	    rects[i].x = arcs[i].x - extra + pDrawable->x;
1302
	    rects[i].y = arcs[i].y - extra + pDrawable->y;
1303
	    rects[i].width = arcs[i].width + lw;
1304
	    rects[i].height = arcs[i].height + lw;
1305
	}
1306
1307
	tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, narcs, rects, CT_NONE);
1308
	REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
1309
		     					pGC->pCompositeClip);
1310
1311
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
1312
1313
	REGION_DESTROY(pDrawable->pScreen, tmpRegion);
1314
	xfree((char *)rects);
1315
    }
1316
1317
    (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, arcs);
1318
1319
    if (narcs) {
1320
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1321
    }
1322
1323
    GC_OP_EPILOGUE(pGC);
1324
}
1325
1326
/*
1327
 * FillPolygon - take bounding box around polygon (and clip).
1328
 */
1329
1330
static void
1331
rfbFillPolygon(register DrawablePtr pDrawable, register GCPtr pGC, int shape, int mode, int count, DDXPointPtr pts)
1332
{
1333
    int i;
1334
    RegionRec tmpRegion;
1335
    BoxRec box;
1336
    GC_OP_PROLOGUE(pDrawable, pGC);
1337
1338
    TRC((stderr,"rfbFillPolygon called\n"));
1339
1340
    if (count) {
1341
	int minX = pts[0].x, maxX = pts[0].x;
1342
	int minY = pts[0].y, maxY = pts[0].y;
1343
1344
	if (mode == CoordModePrevious)
1345
	{
1346
	    int x = pts[0].x, y = pts[0].y;
1347
1348
	    for (i = 1; i < count; i++) {
1349
		x += pts[i].x;
1350
		y += pts[i].y;
1351
		if (x < minX) minX = x;
1352
		if (x > maxX) maxX = x;
1353
		if (y < minY) minY = y;
1354
		if (y > maxY) maxY = y;
1355
	    }
1356
	}
1357
	else
1358
	{
1359
	    for (i = 1; i < count; i++) {
1360
		if (pts[i].x < minX) minX = pts[i].x;
1361
		if (pts[i].x > maxX) maxX = pts[i].x;
1362
		if (pts[i].y < minY) minY = pts[i].y;
1363
		if (pts[i].y > maxY) maxY = pts[i].y;
1364
	    }
1365
	}
1366
1367
	box.x1 = minX + pDrawable->x;
1368
	box.y1 = minY + pDrawable->y;
1369
	box.x2 = maxX + 1 + pDrawable->x;
1370
	box.y2 = maxY + 1 + pDrawable->y;
1371
1372
	SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
1373
1374
	REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
1375
		     					pGC->pCompositeClip);
1376
1377
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
1378
1379
	REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
1380
    }
1381
1382
    (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pts);
1383
1384
    if (count) {
1385
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1386
    }
1387
1388
    GC_OP_EPILOGUE(pGC);
1389
}
1390
1391
/*
1392
 * PolyFillRect - take the union of the given rectangles (and clip).
1393
 */
1394
1395
static void
1396
rfbPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects)
1397
{
1398
    RegionPtr tmpRegion;
1399
    xRectangle *regRects;
1400
    int i;
1401
    GC_OP_PROLOGUE(pDrawable, pGC);
1402
1403
    TRC((stderr,"rfbPolyFillRect called\n"));
1404
1405
    if (nrects) {
1406
	regRects = (xRectangle *)xalloc(nrects*sizeof(xRectangle));
1407
	if (!regRects) {
1408
	    FatalError("rfbPolyFillRect: xalloc failed\n");
1409
	}
1410
1411
	for (i = 0; i < nrects; i++) {
1412
	    regRects[i].x = rects[i].x + pDrawable->x;
1413
	    regRects[i].y = rects[i].y + pDrawable->y;
1414
	    regRects[i].width = rects[i].width;
1415
	    regRects[i].height = rects[i].height;
1416
	}
1417
1418
	tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nrects, regRects,
1419
				    CT_NONE);
1420
	REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
1421
		     					pGC->pCompositeClip);
1422
1423
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
1424
1425
	REGION_DESTROY(pDrawable->pScreen, tmpRegion);
1426
	xfree((char *)regRects);
1427
    }
1428
1429
    (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrects, rects);
1430
1431
    if (nrects) {
1432
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1433
    }
1434
1435
    GC_OP_EPILOGUE(pGC);
1436
}
1437
1438
/*
1439
 * PolyFillArc - take the union of bounding boxes around each arc (and clip).
1440
 * Bounding boxes assume each is a full circle / ellipse.
1441
 */
1442
1443
static void
1444
rfbPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *arcs)
1445
{
1446
    int i, extra, lw;
1447
    RegionPtr tmpRegion;
1448
    xRectangle *rects;
1449
    GC_OP_PROLOGUE(pDrawable, pGC);
1450
1451
    TRC((stderr,"rfbPolyFillArc called\n"));
1452
1453
    if (narcs) {
1454
	rects = (xRectangle *)xalloc(narcs*sizeof(xRectangle));
1455
	if (!rects) {
1456
	    FatalError("rfbPolyFillArc: xalloc failed\n");
1457
	}
1458
1459
	lw = pGC->lineWidth;
1460
	if (lw == 0)
1461
	    lw = 1;
1462
1463
	extra = lw / 2;
1464
1465
	for (i = 0; i < narcs; i++)
1466
	{
1467
	    rects[i].x = arcs[i].x - extra + pDrawable->x;
1468
	    rects[i].y = arcs[i].y - extra + pDrawable->y;
1469
	    rects[i].width = arcs[i].width + lw;
1470
	    rects[i].height = arcs[i].height + lw;
1471
	}
1472
1473
	tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, narcs, rects, CT_NONE);
1474
	REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
1475
		     					pGC->pCompositeClip);
1476
1477
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
1478
1479
	REGION_DESTROY(pDrawable->pScreen, tmpRegion);
1480
	xfree((char *)rects);
1481
    }
1482
1483
    (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, arcs);
1484
1485
    if (narcs) {
1486
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1487
    }
1488
1489
    GC_OP_EPILOGUE(pGC);
1490
}
1491
1492
/*
1493
 * Get a rough bounding box around n characters of the given font.
1494
 */
1495
1496
static void GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y, int n, BoxPtr pbox)
1497
{
1498
    int maxAscent, maxDescent, maxCharWidth;
1499
1500
    if (FONTASCENT(font) > FONTMAXBOUNDS(font,ascent))
1501
	maxAscent = FONTASCENT(font);
1502
    else
1503
	maxAscent = FONTMAXBOUNDS(font,ascent);
1504
1505
    if (FONTDESCENT(font) > FONTMAXBOUNDS(font,descent))
1506
	maxDescent = FONTDESCENT(font);
1507
    else
1508
	maxDescent = FONTMAXBOUNDS(font,descent);
1509
1510
    if (FONTMAXBOUNDS(font,rightSideBearing) > FONTMAXBOUNDS(font,characterWidth))
1511
	maxCharWidth = FONTMAXBOUNDS(font,rightSideBearing);
1512
    else
1513
	maxCharWidth = FONTMAXBOUNDS(font,characterWidth);
1514
1515
    pbox->x1 = pDrawable->x + x;
1516
    pbox->y1 = pDrawable->y + y - maxAscent;
1517
    pbox->x2 = pbox->x1 + maxCharWidth * n;
1518
    pbox->y2 = pbox->y1 + maxAscent + maxDescent;
1519
1520
    if (FONTMINBOUNDS(font,leftSideBearing) < 0) {
1521
	pbox->x1 += FONTMINBOUNDS(font,leftSideBearing);
1522
    }
1523
}
1524
1525
1526
/*
1527
 * PolyText8 - use rough bounding box.
1528
 */
1529
1530
static int
1531
rfbPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars)
1532
{
1533
    int	ret;
1534
    RegionRec tmpRegion;
1535
    BoxRec box;
1536
    GC_OP_PROLOGUE(pDrawable, pGC);
1537
1538
    TRC((stderr,"rfbPolyText8 called '%.*s'\n",count,chars));
1539
1540
    if (count) {
1541
	GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
1542
1543
	SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
1544
1545
	REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
1546
		     					pGC->pCompositeClip);
1547
1548
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
1549
1550
	REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
1551
    }
1552
1553
    ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
1554
1555
    if (count) {
1556
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1557
    }
1558
1559
    GC_OP_EPILOGUE(pGC);
1560
    return ret;
1561
}
1562
1563
/*
1564
 * PolyText16 - use rough bounding box.
1565
 */
1566
1567
static int
1568
rfbPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars)
1569
{
1570
    int	ret;
1571
    RegionRec tmpRegion;
1572
    BoxRec box;
1573
    GC_OP_PROLOGUE(pDrawable, pGC);
1574
1575
    TRC((stderr,"rfbPolyText16 called\n"));
1576
1577
    if (count) {
1578
	GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
1579
1580
	SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
1581
1582
	REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
1583
		     					pGC->pCompositeClip);
1584
1585
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
1586
1587
	REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
1588
    }
1589
1590
    ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
1591
1592
    if (count) {
1593
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1594
    }
1595
1596
    GC_OP_EPILOGUE(pGC);
1597
    return ret;
1598
}
1599
1600
/*
1601
 * ImageText8 - use rough bounding box.
1602
 */
1603
1604
static void
1605
rfbImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars)
1606
{
1607
    RegionRec tmpRegion;
1608
    BoxRec box;
1609
    GC_OP_PROLOGUE(pDrawable, pGC);
1610
1611
    TRC((stderr,"rfbImageText8 called '%.*s'\n",count,chars));
1612
1613
    if (count) {
1614
	GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
1615
1616
	SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
1617
1618
	REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
1619
		     					pGC->pCompositeClip);
1620
1621
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
1622
1623
	REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
1624
    }
1625
1626
    (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
1627
1628
    if (count) {
1629
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1630
    }
1631
1632
    GC_OP_EPILOGUE(pGC);
1633
}
1634
1635
/*
1636
 * ImageText16 - use rough bounding box.
1637
 */
1638
1639
static void
1640
rfbImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars)
1641
{
1642
    RegionRec tmpRegion;
1643
    BoxRec box;
1644
    GC_OP_PROLOGUE(pDrawable, pGC);
1645
1646
    TRC((stderr,"rfbImageText16 called\n"));
1647
1648
    if (count) {
1649
	GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
1650
1651
	SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
1652
1653
	REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
1654
		     					pGC->pCompositeClip);
1655
1656
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
1657
1658
	REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
1659
    }
1660
1661
    (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
1662
1663
    if (count) {
1664
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1665
    }
1666
1667
    GC_OP_EPILOGUE(pGC);
1668
}
1669
1670
/*
1671
 * ImageGlyphBlt - use rough bounding box.
1672
 */
1673
1674
static void
1675
rfbImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase)
1676
{
1677
    RegionRec tmpRegion;
1678
    BoxRec box;
1679
    GC_OP_PROLOGUE(pDrawable, pGC);
1680
1681
    TRC((stderr,"rfbImageGlyphBlt called\n"));
1682
1683
    if (nglyph) {
1684
	GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
1685
1686
	SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
1687
1688
	REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
1689
		     					pGC->pCompositeClip);
1690
1691
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
1692
1693
	REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
1694
    }
1695
1696
    (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci,pglyphBase);
1697
1698
    if (nglyph) {
1699
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1700
    }
1701
1702
    GC_OP_EPILOGUE(pGC);
1703
}
1704
1705
/*
1706
 * PolyGlyphBlt - use rough bounding box.
1707
 */
1708
1709
static void
1710
rfbPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase)
1711
{
1712
    RegionRec tmpRegion;
1713
    BoxRec box;
1714
    GC_OP_PROLOGUE(pDrawable, pGC);
1715
1716
    TRC((stderr,"rfbPolyGlyphBlt called\n"));
1717
1718
    if (nglyph) {
1719
	GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
1720
1721
	SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
1722
1723
	REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
1724
		     					pGC->pCompositeClip);
1725
1726
	ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
1727
1728
	REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
1729
    }
1730
1731
    (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
1732
1733
    if (nglyph) {
1734
	SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1735
    }
1736
1737
    GC_OP_EPILOGUE(pGC);
1738
}
1739
1740
/*
1741
 * PushPixels - be fairly safe - region modified is intersection of the given
1742
 * rectangle with the window clip region.
1743
 */
1744
1745
static void
1746
rfbPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, int w, int h, int x, int y)
1747
{
1748
    RegionRec tmpRegion;
1749
    BoxRec box;
1750
    GC_OP_PROLOGUE(pDrawable, pGC);
1751
1752
    TRC((stderr,"rfbPushPixels called\n"));
1753
1754
    box.x1 = x + pDrawable->x;
1755
    box.y1 = y + pDrawable->y;
1756
    box.x2 = box.x1 + w;
1757
    box.y2 = box.y1 + h;
1758
1759
    SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
1760
1761
    REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
1762
		     					pGC->pCompositeClip);
1763
1764
    ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
1765
1766
    REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
1767
1768
    (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y);
1769
1770
    SCHEDULE_FB_UPDATE(pDrawable->pScreen, pVNC);
1771
1772
    GC_OP_EPILOGUE(pGC);
1773
}
1774
1775
#ifdef RENDER
1776
void
1777
rfbComposite(
1778
    CARD8 op,
1779
    PicturePtr pSrc,
1780
    PicturePtr pMask,
1781
    PicturePtr pDst,
1782
    INT16 xSrc,
1783
    INT16 ySrc,
1784
    INT16 xMask,
1785
    INT16 yMask,
1786
    INT16 xDst,
1787
    INT16 yDst,
1788
    CARD16 width,
1789
    CARD16 height
1790
){
1791
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
1792
    VNCSCREENPTR(pScreen);
1793
    RegionRec tmpRegion;
1794
    BoxRec box;
1795
    PictureScreenPtr ps = GetPictureScreen(pScreen);
1796
1797
    box.x1 = pDst->pDrawable->x + xDst;
1798
    box.y1 = pDst->pDrawable->y + yDst;
1799
    box.x2 = box.x1 + width;
1800
    box.y2 = box.y1 + height;
1801
1802
    REGION_INIT(pScreen, &tmpRegion, &box, 0);
1803
1804
    ADD_TO_MODIFIED_REGION(pScreen, &tmpRegion);
1805
1806
    ps->Composite = pVNC->Composite;
1807
    (*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc,
1808
		     xMask, yMask, xDst, yDst, width, height);
1809
    ps->Composite = rfbComposite;
1810
1811
    SCHEDULE_FB_UPDATE(pScreen, pVNC);
1812
1813
    REGION_UNINIT(pScreen, &tmpRegion);
1814
}
1815
#endif /* RENDER */
1816
1817
/****************************************************************************/
1818
/*
1819
 * Other functions
1820
 */
1821
/****************************************************************************/
1822
1823
/*
1824
 * rfbCopyRegion.  Args are src and dst regions plus a translation (dx,dy).
1825
 * Takes these args together with the existing modified region and possibly an
1826
 * existing copy region and translation.  Produces a combined modified region
1827
 * plus copy region and translation.  Note that the copy region is the
1828
 * destination of the copy.
1829
 *
1830
 * First we trim parts of src which are invalid (ie in the modified region).
1831
 * Then we see if there is any overlap between the src and the existing copy
1832
 * region.  If not then the two copies cannot be combined, so we choose
1833
 * whichever is bigger to form the basis of a new copy, while the other copy is
1834
 * just done the hard way by being added to the modified region.  So if the
1835
 * existing copy is bigger then we simply add the destination of the new copy
1836
 * to the modified region and we're done.  If the new copy is bigger, we add
1837
 * the old copy region to the modified region and behave as though there is no
1838
 * existing copy region.
1839
 * 
1840
 * At this stage we now know that either the two copies can be combined, or
1841
 * that there is no existing copy.  We temporarily add both the existing copy
1842
 * region and dst to the modified region (this is the entire area of the screen
1843
 * affected in any way).  Finally we calculate the new copy region, and remove
1844
 * it from the modified region.
1845
 *
1846
 * Note:
1847
 *   1. The src region is modified by this routine.
1848
 *   2. When the copy region is empty, copyDX and copyDY MUST be set to zero.
1849
 */
1850
1851
static void
1852
rfbCopyRegion(pScreen, cl, src, dst, dx, dy)
1853
    ScreenPtr pScreen;
1854
    rfbClientPtr cl;
1855
    RegionPtr src;
1856
    RegionPtr dst;
1857
    int dx, dy;
1858
{
1859
    RegionRec tmp;
1860
1861
    /* src = src - modifiedRegion */
1862
1863
    REGION_SUBTRACT(pScreen, src, src, &cl->modifiedRegion);
1864
1865
    if (REGION_NOTEMPTY(pScreen, &cl->copyRegion)) {
1866
1867
	REGION_NULL(pScreen, &tmp);
1868
	REGION_INTERSECT(pScreen, &tmp, src, &cl->copyRegion);
1869
1870
	if (REGION_NOTEMPTY(pScreen, &tmp)) {
1871
1872
	    /* if src and copyRegion overlap:
1873
	         src = src intersect copyRegion */
1874
1875
	    REGION_COPY(pScreen, src, &tmp);
1876
1877
	} else {
1878
1879
	    /* if no overlap, find bigger region */
1880
1881
	    int newArea = (((REGION_EXTENTS(pScreen,src))->x2
1882
			    - (REGION_EXTENTS(pScreen,src))->x1)
1883
			   * ((REGION_EXTENTS(pScreen,src))->y2
1884
			      - (REGION_EXTENTS(pScreen,src))->y1));
1885
1886
	    int oldArea = (((REGION_EXTENTS(pScreen,&cl->copyRegion))->x2
1887
			    - (REGION_EXTENTS(pScreen,&cl->copyRegion))->x1)
1888
			   * ((REGION_EXTENTS(pScreen,&cl->copyRegion))->y2
1889
			     - (REGION_EXTENTS(pScreen,&cl->copyRegion))->y1));
1890
1891
	    if (oldArea > newArea) {
1892
1893
		/* existing copy is bigger:
1894
		     modifiedRegion = modifiedRegion union dst
1895
		     copyRegion = copyRegion - dst
1896
		     return */
1897
1898
		REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
1899
			     dst);
1900
		REGION_SUBTRACT(pScreen, &cl->copyRegion, &cl->copyRegion,
1901
				dst);
1902
		if (!REGION_NOTEMPTY(pScreen, &cl->copyRegion)) {
1903
		    cl->copyDX = 0;
1904
		    cl->copyDY = 0;
1905
		}
1906
		return;
1907
	    }
1908
1909
	    /* new copy is bigger:
1910
	         modifiedRegion = modifiedRegion union copyRegion
1911
		 copyRegion = empty */
1912
1913
	    REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
1914
			 &cl->copyRegion);
1915
	    REGION_EMPTY(pScreen, &cl->copyRegion);
1916
	    cl->copyDX = cl->copyDY = 0;
1917
	}
1918
    }
1919
1920
1921
    /* modifiedRegion = modifiedRegion union dst union copyRegion */
1922
1923
    REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, dst);
1924
    REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
1925
		 &cl->copyRegion);
1926
1927
    /* copyRegion = T(src) intersect dst */
1928
1929
    REGION_TRANSLATE(pScreen, src, dx, dy);
1930
    REGION_INTERSECT(pScreen, &cl->copyRegion, src, dst);
1931
1932
    /* modifiedRegion = modifiedRegion - copyRegion */
1933
1934
    REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
1935
		    &cl->copyRegion);
1936
1937
    /* combine new translation T with existing translation */
1938
1939
    if (REGION_NOTEMPTY(pScreen, &cl->copyRegion)) {
1940
	cl->copyDX += dx;
1941
	cl->copyDY += dy;
1942
    } else {
1943
	cl->copyDX = 0;
1944
	cl->copyDY = 0;
1945
    }
1946
}
1947
1948
1949
/*
1950
 * rfbDeferredUpdateCallback() is called when a client's deferredUpdateTimer
1951
 * goes off.
1952
 */
1953
1954
static CARD32
1955
rfbDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
1956
{
1957
  rfbClientPtr cl = (rfbClientPtr)arg;
1958
1959
  rfbSendFramebufferUpdate(cl->pScreen, cl);
1960
1961
  cl->deferredUpdateScheduled = FALSE;
1962
  return 0;
1963
}
1964
1965
1966
/*
1967
 * rfbScheduleDeferredUpdate() is called from the SCHEDULE_FB_UPDATE macro
1968
 * to schedule an update.
1969
 */
1970
1971
static void
1972
rfbScheduleDeferredUpdate(ScreenPtr pScreen, rfbClientPtr cl)
1973
{
1974
    if (rfbDeferUpdateTime != 0) {
1975
	cl->deferredUpdateTimer = TimerSet(cl->deferredUpdateTimer, 0,
1976
					   rfbDeferUpdateTime,
1977
					   rfbDeferredUpdateCallback, cl);
1978
	cl->deferredUpdateScheduled = TRUE;
1979
    } else {
1980
	rfbSendFramebufferUpdate(pScreen, cl);
1981
    }
1982
}
1983
1984
1985
/*
1986
 * PrintRegion is useful for debugging.
1987
 */
1988
1989
#ifdef DEBUG
1990
static void
1991
PrintRegion(ScreenPtr pScreen, RegionPtr reg)
1992
{
1993
    int nrects = REGION_NUM_RECTS(reg);
1994
    int i;
1995
1996
    ErrorF("Region num rects %d extents %d,%d %d,%d\n",nrects,
1997
	   (REGION_EXTENTS(pScreen,reg))->x1,
1998
	   (REGION_EXTENTS(pScreen,reg))->y1,
1999
	   (REGION_EXTENTS(pScreen,reg))->x2,
2000
	   (REGION_EXTENTS(pScreen,reg))->y2);
2001
2002
    for (i = 0; i < nrects; i++) {
2003
	ErrorF("    rect %d,%d %dx%d\n",
2004
	       REGION_RECTS(reg)[i].x1,
2005
	       REGION_RECTS(reg)[i].y1,
2006
	       REGION_RECTS(reg)[i].x2-REGION_RECTS(reg)[i].x1,
2007
	       REGION_RECTS(reg)[i].y2-REGION_RECTS(reg)[i].y1);
2008
    }
2009
}
2010
#endif
2011
2012
/**
2013
 * Allow scheduling updates from other functions in other files.
2014
 */
2015
void
2016
rfbScheduleUpdate(ScreenPtr pScreen)
2017
{
2018
    VNCSCREENPTR(pScreen);
2019
    SCHEDULE_FB_UPDATE(pScreen, pVNC);
2020
}
(-)xorg-server-1.4.orig/hw/vnc/hextile.c (+350 lines)
Line 0 Link Here
1
/*
2
 * hextile.c
3
 *
4
 * Routines to implement Hextile Encoding
5
 *
6
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
7
 */
8
9
/*
10
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
11
 *
12
 *  This is free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 2 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  This software is distributed in the hope that it will be useful,
18
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 *  GNU General Public License for more details.
21
 *
22
 *  You should have received a copy of the GNU General Public License
23
 *  along with this software; if not, write to the Free Software
24
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
25
 *  USA.
26
 */
27
#ifdef HAVE_DIX_CONFIG_H
28
#include <dix-config.h>
29
#endif
30
31
#include <stdio.h>
32
#include "rfb.h"
33
34
static Bool sendHextiles8(rfbClientPtr cl, int x, int y, int w, int h);
35
static Bool sendHextiles16(rfbClientPtr cl, int x, int y, int w, int h);
36
static Bool sendHextiles32(rfbClientPtr cl, int x, int y, int w, int h);
37
38
39
/*
40
 * rfbSendRectEncodingHextile - send a rectangle using hextile encoding.
41
 */
42
43
Bool
44
rfbSendRectEncodingHextile(cl, x, y, w, h)
45
    rfbClientPtr cl;
46
    int x, y, w, h;
47
{
48
    VNCSCREENPTR(cl->pScreen);
49
    rfbFramebufferUpdateRectHeader rect;
50
51
    if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
52
	if (!rfbSendUpdateBuf(cl))
53
	    return FALSE;
54
    }
55
56
    rect.r.x = Swap16IfLE(x);
57
    rect.r.y = Swap16IfLE(y);
58
    rect.r.w = Swap16IfLE(w);
59
    rect.r.h = Swap16IfLE(h);
60
    rect.encoding = Swap32IfLE(rfbEncodingHextile);
61
62
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,
63
	   sz_rfbFramebufferUpdateRectHeader);
64
    pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
65
66
    cl->rfbRectanglesSent[rfbEncodingHextile]++;
67
    cl->rfbBytesSent[rfbEncodingHextile] += sz_rfbFramebufferUpdateRectHeader;
68
69
    switch (cl->format.bitsPerPixel) {
70
    case 8:
71
	return sendHextiles8(cl, x, y, w, h);
72
    case 16:
73
	return sendHextiles16(cl, x, y, w, h);
74
    case 32:
75
	return sendHextiles32(cl, x, y, w, h);
76
    }
77
78
    rfbLog("rfbSendRectEncodingHextile: bpp %d?\n", cl->format.bitsPerPixel);
79
    return FALSE;
80
}
81
82
83
#define PUT_PIXEL8(pix) (pVNC->updateBuf[pVNC->ublen++] = (pix))
84
85
#define PUT_PIXEL16(pix) (pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[0], \
86
			  pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[1])
87
88
#define PUT_PIXEL32(pix) (pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[0], \
89
			  pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[1], \
90
			  pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[2], \
91
			  pVNC->updateBuf[pVNC->ublen++] = ((char*)&(pix))[3])
92
93
94
#define DEFINE_SEND_HEXTILES(bpp)					      \
95
									      \
96
									      \
97
static Bool subrectEncode##bpp(ScreenPtr pScreen, CARD##bpp *data, int w,     \
98
			       int h, CARD##bpp bg,   			      \
99
			       CARD##bpp fg, Bool mono);		      \
100
static void testColours##bpp(CARD##bpp *data, int size, Bool *mono,	      \
101
			     Bool *solid, CARD##bpp *bg, CARD##bpp *fg);      \
102
									      \
103
									      \
104
/*									      \
105
 * rfbSendHextiles							      \
106
 */									      \
107
									      \
108
static Bool								      \
109
sendHextiles##bpp(cl, rx, ry, rw, rh)					      \
110
    rfbClientPtr cl;							      \
111
    int rx, ry, rw, rh;							      \
112
{									      \
113
    VNCSCREENPTR(cl->pScreen);						      \
114
    int x, y, w, h;							      \
115
    int startUblen;							      \
116
    CARD##bpp bg = 0, fg = 0, newBg, newFg;				      \
117
    Bool mono, solid;							      \
118
    Bool validBg = FALSE;						      \
119
    Bool validFg = FALSE;						      \
120
    CARD##bpp clientPixelData[16*16*(bpp/8)];				      \
121
									      \
122
    for (y = ry; y < ry+rh; y += 16) {					      \
123
	for (x = rx; x < rx+rw; x += 16) {				      \
124
	    w = h = 16;							      \
125
	    if (rx+rw - x < 16)						      \
126
		w = rx+rw - x;						      \
127
	    if (ry+rh - y < 16)						      \
128
		h = ry+rh - y;						      \
129
									      \
130
	    if ((pVNC->ublen + 1 + (2 + 16 * 16) * (bpp/8)) > UPDATE_BUF_SIZE) { \
131
		if (!rfbSendUpdateBuf(cl))				      \
132
		    return FALSE;					      \
133
	    }								      \
134
									      \
135
	    (*cl->translateFn)(cl->pScreen, cl->translateLookupTable,	      \
136
			       &pVNC->rfbServerFormat,			      \
137
			       &cl->format, (unsigned char *)clientPixelData,   \
138
			       pVNC->paddedWidthInBytes, w, h, x, y); 	      \
139
									      \
140
	    startUblen = pVNC->ublen;					      \
141
	    pVNC->updateBuf[startUblen] = 0;				      \
142
	    pVNC->ublen++;						      \
143
									      \
144
	    testColours##bpp(clientPixelData, w * h,			      \
145
			     &mono, &solid, &newBg, &newFg);		      \
146
									      \
147
	    if (!validBg || (newBg != bg)) {				      \
148
		validBg = TRUE;						      \
149
		bg = newBg;						      \
150
		pVNC->updateBuf[startUblen] |= rfbHextileBackgroundSpecified; \
151
		PUT_PIXEL##bpp(bg);					      \
152
	    }								      \
153
									      \
154
	    if (solid) {						      \
155
		cl->rfbBytesSent[rfbEncodingHextile] += pVNC->ublen - startUblen;  \
156
		continue;						      \
157
	    }								      \
158
									      \
159
	    pVNC->updateBuf[startUblen] |= rfbHextileAnySubrects;	      \
160
									      \
161
	    if (mono) {							      \
162
		if (!validFg || (newFg != fg)) {			      \
163
		    validFg = TRUE;					      \
164
		    fg = newFg;						      \
165
		    pVNC->updateBuf[startUblen] |= rfbHextileForegroundSpecified; \
166
		    PUT_PIXEL##bpp(fg);					      \
167
		}							      \
168
	    } else {							      \
169
		validFg = FALSE;					      \
170
		pVNC->updateBuf[startUblen] |= rfbHextileSubrectsColoured;    \
171
	    }								      \
172
									      \
173
	    if (!subrectEncode##bpp(cl->pScreen, clientPixelData, w, h, bg, fg, mono)) {   \
174
		/* encoding was too large, use raw */			      \
175
		validBg = FALSE;					      \
176
		validFg = FALSE;					      \
177
		pVNC->ublen = startUblen;				      \
178
		pVNC->updateBuf[pVNC->ublen++] = rfbHextileRaw;		      \
179
		(*cl->translateFn)(cl->pScreen, cl->translateLookupTable,     \
180
				   &pVNC->rfbServerFormat, &cl->format, \
181
				   (unsigned char *)clientPixelData,		      \
182
				   pVNC->paddedWidthInBytes, w, h, x, y);     \
183
									      \
184
		memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)clientPixelData,\
185
		       w * h * (bpp/8));				      \
186
									      \
187
		pVNC->ublen += w * h * (bpp/8);				      \
188
	    }								      \
189
									      \
190
	    cl->rfbBytesSent[rfbEncodingHextile] += pVNC->ublen - startUblen; \
191
	}								      \
192
    }									      \
193
									      \
194
    return TRUE;							      \
195
}									      \
196
									      \
197
									      \
198
static Bool								      \
199
subrectEncode##bpp(ScreenPtr pScreen, CARD##bpp *data, int w, int h,          \
200
		   CARD##bpp bg, CARD##bpp fg, Bool mono)		      \
201
{									      \
202
    VNCSCREENPTR(pScreen);						      \
203
    CARD##bpp clientdata;						      \
204
    int x,y;								      \
205
    int i,j;								      \
206
    int hx=0,hy,vx=0,vy;						      \
207
    int hyflag;								      \
208
    CARD##bpp *seg;							      \
209
    CARD##bpp *line;							      \
210
    int hw,hh,vw,vh;							      \
211
    int thex,they,thew,theh;						      \
212
    int numsubs = 0;							      \
213
    int newLen;								      \
214
    int nSubrectsUblen;							      \
215
									      \
216
    nSubrectsUblen = pVNC->ublen;					      \
217
    pVNC->ublen++;							      \
218
									      \
219
    for (y=0; y<h; y++) {						      \
220
	line = data+(y*w);						      \
221
	for (x=0; x<w; x++) {						      \
222
	    if (line[x] != bg) {					      \
223
		clientdata = line[x];					      \
224
		hy = y-1;						      \
225
		hyflag = 1;						      \
226
		for (j=y; j<h; j++) {					      \
227
		    seg = data+(j*w);					      \
228
		    if (seg[x] != clientdata) {break;}			      \
229
		    i = x;						      \
230
		    while ((seg[i] == clientdata) && (i < w)) i += 1;	      \
231
		    i -= 1;						      \
232
		    if (j == y) vx = hx = i;				      \
233
		    if (i < vx) vx = i;					      \
234
		    if ((hyflag > 0) && (i >= hx)) {			      \
235
			hy += 1;					      \
236
		    } else {						      \
237
			hyflag = 0;					      \
238
		    }							      \
239
		}							      \
240
		vy = j-1;						      \
241
									      \
242
		/* We now have two possible subrects: (x,y,hx,hy) and	      \
243
		 * (x,y,vx,vy).  We'll choose the bigger of the two.	      \
244
		 */							      \
245
		hw = hx-x+1;						      \
246
		hh = hy-y+1;						      \
247
		vw = vx-x+1;						      \
248
		vh = vy-y+1;						      \
249
									      \
250
		thex = x;						      \
251
		they = y;						      \
252
									      \
253
		if ((hw*hh) > (vw*vh)) {				      \
254
		    thew = hw;						      \
255
		    theh = hh;						      \
256
		} else {						      \
257
		    thew = vw;						      \
258
		    theh = vh;						      \
259
		}							      \
260
									      \
261
		if (mono) {						      \
262
		    newLen = pVNC->ublen - nSubrectsUblen + 2;		      \
263
		} else {						      \
264
		    newLen = pVNC->ublen - nSubrectsUblen + bpp/8 + 2;	      \
265
		}							      \
266
									      \
267
		if (newLen > (w * h * (bpp/8)))				      \
268
		    return FALSE;					      \
269
									      \
270
		numsubs += 1;						      \
271
									      \
272
		if (!mono) PUT_PIXEL##bpp(clientdata);			      \
273
									      \
274
		pVNC->updateBuf[pVNC->ublen++] = rfbHextilePackXY(thex,they); \
275
		pVNC->updateBuf[pVNC->ublen++] = rfbHextilePackWH(thew,theh); \
276
									      \
277
		/*							      \
278
		 * Now mark the subrect as done.			      \
279
		 */							      \
280
		for (j=they; j < (they+theh); j++) {			      \
281
		    for (i=thex; i < (thex+thew); i++) {		      \
282
			data[j*w+i] = bg;				      \
283
		    }							      \
284
		}							      \
285
	    }								      \
286
	}								      \
287
    }									      \
288
									      \
289
    pVNC->updateBuf[nSubrectsUblen] = numsubs;				      \
290
									      \
291
    return TRUE;							      \
292
}									      \
293
									      \
294
									      \
295
/*									      \
296
 * testColours() tests if there are one (solid), two (mono) or more	      \
297
 * colours in a tile and gets a reasonable guess at the best background	      \
298
 * pixel, and the foreground pixel for mono.				      \
299
 */									      \
300
									      \
301
static void								      \
302
testColours##bpp(data,size,mono,solid,bg,fg)				      \
303
    CARD##bpp *data;							      \
304
    int size;								      \
305
    Bool *mono;								      \
306
    Bool *solid;							      \
307
    CARD##bpp *bg;							      \
308
    CARD##bpp *fg;							      \
309
{									      \
310
    CARD##bpp colour1 = 0, colour2 = 0;					      \
311
    int n1 = 0, n2 = 0;							      \
312
    *mono = TRUE;							      \
313
    *solid = TRUE;							      \
314
									      \
315
    for (; size > 0; size--, data++) {					      \
316
									      \
317
	if (n1 == 0)							      \
318
	    colour1 = *data;						      \
319
									      \
320
	if (*data == colour1) {						      \
321
	    n1++;							      \
322
	    continue;							      \
323
	}								      \
324
									      \
325
	if (n2 == 0) {							      \
326
	    *solid = FALSE;						      \
327
	    colour2 = *data;						      \
328
	}								      \
329
									      \
330
	if (*data == colour2) {						      \
331
	    n2++;							      \
332
	    continue;							      \
333
	}								      \
334
									      \
335
	*mono = FALSE;							      \
336
	break;								      \
337
    }									      \
338
									      \
339
    if (n1 > n2) {							      \
340
	*bg = colour1;							      \
341
	*fg = colour2;							      \
342
    } else {								      \
343
	*bg = colour2;							      \
344
	*fg = colour1;							      \
345
    }									      \
346
}
347
348
DEFINE_SEND_HEXTILES(8)
349
DEFINE_SEND_HEXTILES(16)
350
DEFINE_SEND_HEXTILES(32)
(-)xorg-server-1.4.orig/hw/vnc/httpd.c (+519 lines)
Line 0 Link Here
1
/*
2
 * httpd.c - a simple HTTP server
3
 *
4
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
5
 */
6
7
/*
8
 *  Copyright (C) 2002 Constantin Kaplinsky.  All Rights Reserved.
9
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
10
 *
11
 *  This is free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  This software is distributed in the hope that it will be useful,
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *  GNU General Public License for more details.
20
 *
21
 *  You should have received a copy of the GNU General Public License
22
 *  along with this software; if not, write to the Free Software
23
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
24
 *  USA.
25
 */
26
#ifdef HAVE_DIX_CONFIG_H
27
#include <dix-config.h>
28
#endif
29
30
#include <sys/types.h>
31
#include <sys/time.h>
32
#include <sys/socket.h>
33
#include <netinet/in.h>
34
#include <netinet/tcp.h>
35
#include <fcntl.h>
36
#include <errno.h>
37
#include <arpa/inet.h>
38
#include <pwd.h>
39
#include <netdb.h>
40
41
#ifndef USE_LIBWRAP
42
#define USE_LIBWRAP 0
43
#endif
44
#if USE_LIBWRAP
45
#include <tcpd.h>
46
#endif
47
48
#include "rfb.h"
49
50
#define NOT_FOUND_STR "HTTP/1.0 404 Not found\r\n\r\n" \
51
    "<HEAD><TITLE>File Not Found</TITLE></HEAD>\n" \
52
    "<BODY><H1>File Not Found</H1></BODY>\n"
53
54
#define OK_STR "HTTP/1.0 200 OK\r\n\r\n"
55
56
static void httpProcessInput(ScreenPtr pScreen);
57
static Bool compareAndSkip(char **ptr, const char *str);
58
static Bool parseParams(const char *request, char *result, int max_bytes);
59
static Bool validateString(char *str);
60
61
/*
62
 * httpInitSockets sets up the TCP socket to listen for HTTP connections.
63
 */
64
65
Bool
66
httpInitSockets(ScreenPtr pScreen)
67
{
68
    VNCSCREENPTR(pScreen);
69
70
    if (!pVNC->httpDir)
71
	return FALSE;
72
73
    pVNC->buf_filled = 0;
74
75
    if (pVNC->httpPort == 0) {
76
	pVNC->httpPort = 5800 + atoi(display) + pScreen->myNum;
77
    }
78
79
    if ((pVNC->httpListenSock = ListenOnTCPPort(pScreen, pVNC->httpPort)) < 0) {
80
	rfbLog("ListenOnTCPPort %d failed\n",pVNC->httpPort);
81
	pVNC->httpPort = 0;
82
	return FALSE;
83
    }
84
85
    rfbLog("Listening for HTTP connections on TCP port %d\n", pVNC->httpPort);
86
    rfbLog("  URL http://%s:%d\n",rfbThisHost,pVNC->httpPort);
87
88
    AddEnabledDevice(pVNC->httpListenSock);
89
90
    return TRUE;
91
}
92
93
94
/*
95
 * httpCheckFds is called from ProcessInputEvents to check for input on the
96
 * HTTP socket(s).  If there is input to process, httpProcessInput is called.
97
 */
98
99
void
100
httpCheckFds(ScreenPtr pScreen)
101
{
102
    VNCSCREENPTR(pScreen);
103
    int nfds;
104
    fd_set fds;
105
    struct timeval tv;
106
    struct sockaddr_in addr;
107
    SOCKLEN_T addrlen = sizeof(addr);
108
109
    if (!pVNC->httpDir)
110
	return;
111
112
    FD_ZERO(&fds);
113
    FD_SET(pVNC->httpListenSock, &fds);
114
    if (pVNC->httpSock >= 0) {
115
	FD_SET(pVNC->httpSock, &fds);
116
    }
117
    tv.tv_sec = 0;
118
    tv.tv_usec = 0;
119
    nfds = select(max(pVNC->httpSock,pVNC->httpListenSock) + 1, &fds, NULL, NULL, &tv);
120
    if (nfds == 0) {
121
	return;
122
    }
123
    if (nfds < 0) {
124
	if (errno != EINTR) 
125
		rfbLogPerror("httpCheckFds: select");
126
	return;
127
    }
128
129
    if ((pVNC->httpSock >= 0) && FD_ISSET(pVNC->httpSock, &fds)) {
130
	httpProcessInput(pScreen);
131
    }
132
133
    if (FD_ISSET(pVNC->httpListenSock, &fds)) {
134
	int flags;
135
136
	if (pVNC->httpSock >= 0) close(pVNC->httpSock);
137
138
	if ((pVNC->httpSock = accept(pVNC->httpListenSock,
139
			       (struct sockaddr *)&addr, &addrlen)) < 0) {
140
	    rfbLogPerror("httpCheckFds: accept");
141
	    return;
142
	}
143
144
#if USE_LIBWRAP
145
	if (!hosts_ctl("Xvnc", STRING_UNKNOWN, inet_ntoa(addr.sin_addr),
146
		       STRING_UNKNOWN)) {
147
	    rfbLog("Rejected HTTP connection from client %s\n",
148
		   inet_ntoa(addr.sin_addr));
149
  	    close(pVNC->httpSock);
150
  	    pVNC->httpSock = -1;
151
  	    return;
152
  	}
153
#endif
154
155
	flags = fcntl (pVNC->httpSock, F_GETFL);
156
157
	if (flags == -1 ||
158
	fcntl (pVNC->httpSock, F_SETFL, flags | O_NONBLOCK) == -1) {
159
	    rfbLogPerror("httpCheckFds: fcntl");
160
	    close (pVNC->httpSock);
161
	    pVNC->httpSock = -1;
162
	    return;
163
	}
164
165
	AddEnabledDevice(pVNC->httpSock);
166
    }
167
}
168
169
170
static void
171
httpCloseSock(ScreenPtr pScreen)
172
{
173
    VNCSCREENPTR(pScreen);
174
    close(pVNC->httpSock);
175
    RemoveEnabledDevice(pVNC->httpSock);
176
    pVNC->httpSock = -1;
177
    pVNC->buf_filled = 0;
178
}
179
180
181
/*
182
 * httpProcessInput is called when input is received on the HTTP socket.
183
 */
184
185
static void
186
httpProcessInput(ScreenPtr pScreen)
187
{
188
    VNCSCREENPTR(pScreen);
189
    struct sockaddr_in addr;
190
    SOCKLEN_T addrlen = sizeof(addr);
191
    char fullFname[512];
192
    char params[1024];
193
    char *ptr;
194
    char *fname;
195
    int maxFnameLen;
196
    int fd;
197
    Bool performSubstitutions = FALSE;
198
    char str[256];
199
    struct passwd *user = getpwuid(getuid());
200
  
201
    if (strlen(pVNC->httpDir) > 255) {
202
	rfbLog("-httpd directory too long\n");
203
  	httpCloseSock(pScreen);
204
	return;
205
    }
206
    strcpy(fullFname, pVNC->httpDir);
207
    fname = &fullFname[strlen(fullFname)];
208
    maxFnameLen = 511 - strlen(fullFname);
209
  
210
    /* Read data from the HTTP client until we get a complete request. */
211
    while (1) {
212
	ssize_t got = read (pVNC->httpSock, pVNC->buf + pVNC->buf_filled,
213
			    sizeof (pVNC->buf) - pVNC->buf_filled - 1);
214
215
	if (got <= 0) {
216
	    if (got == 0) {
217
		rfbLog("httpd: premature connection close\n");
218
	    } else {
219
		if (errno == EAGAIN) {
220
		    return;
221
		}
222
		rfbLogPerror("httpProcessInput: read");
223
	    }
224
	    httpCloseSock(pScreen);
225
  	    return;
226
	}
227
  
228
	pVNC->buf_filled += got;
229
	pVNC->buf[pVNC->buf_filled] = '\0';
230
  
231
	/* Is it complete yet (is there a blank line)? */
232
	if (strstr (pVNC->buf, "\r\r") || strstr (pVNC->buf, "\n\n") ||
233
	    strstr (pVNC->buf, "\r\n\r\n") || strstr (pVNC->buf, "\n\r\n\r"))
234
	    break;
235
    }
236
  
237
    /* Process the request. */
238
    if (strncmp(pVNC->buf, "GET ", 4)) {
239
	rfbLog("httpd: no GET line\n");
240
	httpCloseSock(pScreen);
241
	return;
242
    } else {
243
	/* Only use the first line. */
244
	pVNC->buf[strcspn(pVNC->buf, "\n\r")] = '\0';
245
    }
246
  
247
    if (strlen(pVNC->buf) > maxFnameLen) {
248
	rfbLog("httpd: GET line too long\n");
249
	httpCloseSock(pScreen);
250
	return;
251
    }
252
  
253
    if (sscanf(pVNC->buf, "GET %s HTTP/1.0", fname) != 1) {
254
	rfbLog("httpd: couldn't parse GET line\n");
255
	httpCloseSock(pScreen);
256
	return;
257
    }
258
  
259
    if (fname[0] != '/') {
260
	rfbLog("httpd: filename didn't begin with '/'\n");
261
	WriteExact(pVNC->httpSock, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
262
	httpCloseSock(pScreen);
263
	return;
264
    }
265
  
266
    if (strchr(fname+1, '/') != NULL) {
267
	rfbLog("httpd: asking for file in other directory\n");
268
	WriteExact(pVNC->httpSock, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
269
	httpCloseSock(pScreen);
270
	return;
271
    }
272
  
273
    getpeername(pVNC->httpSock, (struct sockaddr *)&addr, &addrlen);
274
    rfbLog("httpd: get '%s' for %s\n", fname+1,
275
	   inet_ntoa(addr.sin_addr));
276
277
    /* Extract parameters from the URL string if necessary */
278
279
    params[0] = '\0';
280
    ptr = strchr(fname, '?');
281
    if (ptr != NULL) {
282
	*ptr = '\0';
283
	if (!parseParams(&ptr[1], params, 1024)) {
284
	    params[0] = '\0';
285
	    rfbLog("httpd: bad parameters in the URL\n");
286
	}
287
    }
288
289
    /* If we were asked for '/', actually read the file index.vnc */
290
291
    if (strcmp(fname, "/") == 0) {
292
	strcpy(fname, "/index.vnc");
293
	rfbLog("httpd: defaulting to '%s'\n", fname+1);
294
    }
295
296
    /* Substitutions are performed on files ending .vnc */
297
298
    if (strlen(fname) >= 4 && strcmp(&fname[strlen(fname)-4], ".vnc") == 0) {
299
	performSubstitutions = TRUE;
300
    }
301
302
    /* Open the file */
303
304
    if ((fd = open(fullFname, O_RDONLY)) < 0) {
305
	rfbLogPerror("httpProcessInput: open");
306
	WriteExact(pVNC->httpSock, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
307
	httpCloseSock(pScreen);
308
	return;
309
    }
310
311
    WriteExact(pVNC->httpSock, OK_STR, strlen(OK_STR));
312
313
    while (1) {
314
	int n = read(fd, pVNC->buf, HTTP_BUF_SIZE-1);
315
	if (n < 0) {
316
	    rfbLogPerror("httpProcessInput: read");
317
	    close(fd);
318
	    httpCloseSock(pScreen);
319
	    return;
320
	}
321
322
	if (n == 0)
323
	    break;
324
325
	if (performSubstitutions) {
326
327
	    /* Substitute $WIDTH, $HEIGHT, etc with the appropriate values.
328
	       This won't quite work properly if the .vnc file is longer than
329
	       HTTP_BUF_SIZE, but it's reasonable to assume that .vnc files will
330
	       always be short. */
331
332
	    char *ptr = pVNC->buf;
333
	    char *dollar;
334
	    pVNC->buf[n] = 0; /* make sure it's null-terminated */
335
336
	    while ((dollar = strchr(ptr, '$'))) {
337
		WriteExact(pVNC->httpSock, ptr, (dollar - ptr));
338
339
		ptr = dollar;
340
341
		if (compareAndSkip(&ptr, "$WIDTH")) {
342
343
		    sprintf(str, "%d", pVNC->width);
344
		    WriteExact(pVNC->httpSock, str, strlen(str));
345
346
		} else if (compareAndSkip(&ptr, "$HEIGHT")) {
347
348
		    sprintf(str, "%d", pVNC->height);
349
		    WriteExact(pVNC->httpSock, str, strlen(str));
350
351
		} else if (compareAndSkip(&ptr, "$APPLETWIDTH")) {
352
353
		    sprintf(str, "%d", pVNC->width);
354
		    WriteExact(pVNC->httpSock, str, strlen(str));
355
356
		} else if (compareAndSkip(&ptr, "$APPLETHEIGHT")) {
357
358
		    sprintf(str, "%d", pVNC->height + 32);
359
		    WriteExact(pVNC->httpSock, str, strlen(str));
360
361
		} else if (compareAndSkip(&ptr, "$PORT")) {
362
363
		    sprintf(str, "%d", pVNC->rfbPort);
364
		    WriteExact(pVNC->httpSock, str, strlen(str));
365
366
		} else if (compareAndSkip(&ptr, "$DESKTOP")) {
367
368
		    WriteExact(pVNC->httpSock, desktopName, strlen(desktopName));
369
370
		} else if (compareAndSkip(&ptr, "$DISPLAY")) {
371
372
		    sprintf(str, "%s:%s", rfbThisHost, display);
373
		    WriteExact(pVNC->httpSock, str, strlen(str));
374
375
		} else if (compareAndSkip(&ptr, "$USER")) {
376
377
		    if (user) {
378
			WriteExact(pVNC->httpSock, user->pw_name,
379
				   strlen(user->pw_name));
380
		    } else {
381
			WriteExact(pVNC->httpSock, "?", 1);
382
		    }
383
384
		} else if (compareAndSkip(&ptr, "$PARAMS")) {
385
386
		    if (params[0] != '\0')
387
			WriteExact(pVNC->httpSock, params, strlen(params));
388
389
		} else {
390
		    if (!compareAndSkip(&ptr, "$$"))
391
			ptr++;
392
393
		    if (WriteExact(pVNC->httpSock, "$", 1) < 0) {
394
			close(fd);
395
			httpCloseSock(pScreen);
396
			return;
397
		    }
398
		}
399
	    }
400
	    if (WriteExact(pVNC->httpSock, ptr, (&pVNC->buf[n] - ptr)) < 0)
401
		break;
402
403
	} else {
404
405
	    /* For files not ending .vnc, just write out the buffer */
406
407
	    if (WriteExact(pVNC->httpSock, pVNC->buf, n) < 0)
408
		break;
409
	}
410
    }
411
412
    close(fd);
413
    httpCloseSock(pScreen);
414
}
415
416
417
static Bool
418
compareAndSkip(char **ptr, const char *str)
419
{
420
    if (strncmp(*ptr, str, strlen(str)) == 0) {
421
	*ptr += strlen(str);
422
	return TRUE;
423
    }
424
425
    return FALSE;
426
}
427
428
/*
429
 * Parse the request tail after the '?' character, and format a sequence
430
 * of <param> tags for inclusion into an HTML page with embedded applet.
431
 */
432
433
static Bool
434
parseParams(const char *request, char *result, int max_bytes)
435
{
436
    char param_request[128];
437
    char param_formatted[196];
438
    const char *tail;
439
    char *delim_ptr;
440
    char *value_str;
441
    int cur_bytes, len;
442
443
    result[0] = '\0';
444
    cur_bytes = 0;
445
446
    tail = request;
447
    for (;;) {
448
	/* Copy individual "name=value" string into a buffer */
449
	delim_ptr = strchr((char *)tail, '&');
450
	if (delim_ptr == NULL) {
451
	    if (strlen(tail) >= sizeof(param_request)) {
452
		return FALSE;
453
	    }
454
	    strcpy(param_request, tail);
455
	} else {
456
	    len = delim_ptr - tail;
457
	    if (len >= sizeof(param_request)) {
458
		return FALSE;
459
	    }
460
	    memcpy(param_request, tail, len);
461
	    param_request[len] = '\0';
462
	}
463
464
	/* Split the request into parameter name and value */
465
	value_str = strchr(&param_request[1], '=');
466
	if (value_str == NULL) {
467
	    return FALSE;
468
	}
469
	*value_str++ = '\0';
470
	if (strlen(value_str) == 0) {
471
	    return FALSE;
472
	}
473
474
	/* Validate both parameter name and value */
475
	if (!validateString(param_request) || !validateString(value_str)) {
476
	    return FALSE;
477
	}
478
479
	/* Prepare HTML-formatted representation of the name=value pair */
480
	len = sprintf(param_formatted,
481
		      "<PARAM NAME=\"%s\" VALUE=\"%s\">\n",
482
		      param_request, value_str);
483
	if (cur_bytes + len + 1 > max_bytes) {
484
	    return FALSE;
485
	}
486
	strcat(result, param_formatted);
487
	cur_bytes += len;
488
489
	/* Go to the next parameter */
490
	if (delim_ptr == NULL) {
491
	    break;
492
	}
493
	tail = delim_ptr + 1;
494
    }
495
    return TRUE;
496
}
497
498
/*
499
 * Check if the string consists only of alphanumeric characters, '+'
500
 * signs, underscores, and dots. Replace all '+' signs with spaces.
501
 */
502
503
static Bool
504
validateString(char *str)
505
{
506
    char *ptr;
507
508
    for (ptr = str; *ptr != '\0'; ptr++) {
509
	if (!isalnum(*ptr) && *ptr != '_' && *ptr != '.') {
510
	    if (*ptr == '+') {
511
		*ptr = ' ';
512
	    } else {
513
		return FALSE;
514
	    }
515
	}
516
    }
517
    return TRUE;
518
}
519
(-)xorg-server-1.4.orig/hw/vnc/init.c (+1075 lines)
Line 0 Link Here
1
/*
2
 * init.c
3
 *
4
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
5
 */
6
7
/*
8
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
9
 *
10
 *  This is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  This software is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this software; if not, write to the Free Software
22
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
23
 *  USA.
24
 */
25
26
/*
27
28
Copyright (c) 1993  X Consortium
29
30
Permission is hereby granted, free of charge, to any person obtaining
31
a copy of this software and associated documentation files (the
32
"Software"), to deal in the Software without restriction, including
33
without limitation the rights to use, copy, modify, merge, publish,
34
distribute, sublicense, and/or sell copies of the Software, and to
35
permit persons to whom the Software is furnished to do so, subject to
36
the following conditions:
37
38
The above copyright notice and this permission notice shall be included
39
in all copies or substantial portions of the Software.
40
41
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
42
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
43
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
44
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
45
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
46
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
47
OTHER DEALINGS IN THE SOFTWARE.
48
49
Except as contained in this notice, the name of the X Consortium shall
50
not be used in advertising or otherwise to promote the sale, use or
51
other dealings in this Software without prior written authorization
52
from the X Consortium.
53
54
*/
55
56
/* Use ``#define CORBA'' to enable CORBA control interface */
57
58
/* XXX this definition should probably go elsewhere */
59
#ifdef HAVE_DIX_CONFIG_H
60
#include <dix-config.h>
61
#endif
62
63
#ifndef XVNCRELEASE
64
#define XVNCRELEASE "X.org/xf4vnc custom version"
65
#endif
66
67
#include <stdio.h>
68
#include <unistd.h>
69
#include <stdarg.h>
70
#include <sys/types.h>
71
#include <sys/socket.h>
72
#include <netinet/in.h>
73
#include <netdb.h>
74
#include "X11/X.h"
75
#define NEED_EVENTS
76
#include "X11/Xproto.h"
77
#include "X11/Xos.h"
78
#include "scrnintstr.h"
79
#include "servermd.h"
80
#include "fb.h"
81
#include "mibstore.h"
82
#include "colormapst.h"
83
#include "gcstruct.h"
84
#include "input.h"
85
#include "mipointer.h"
86
#include "dixstruct.h"
87
#include <X11/Xatom.h>
88
#include <errno.h>
89
#include <sys/param.h>
90
#include "dix.h"
91
#include "micmap.h"
92
#include "rfb.h"
93
94
#ifdef CORBA
95
#include <vncserverctrl.h>
96
#endif
97
98
#define RFB_DEFAULT_WIDTH  640
99
#define RFB_DEFAULT_HEIGHT 480
100
#define RFB_DEFAULT_DEPTH  8
101
#define RFB_DEFAULT_WHITEPIXEL 0
102
#define RFB_DEFAULT_BLACKPIXEL 1
103
104
static unsigned long VNCGeneration = 0;
105
rfbScreenInfo rfbScreen;
106
int rfbGCIndex;
107
extern char dispatchExceptionAtReset;
108
109
extern void VncExtensionInit(void);
110
111
static Bool initOutputCalled = FALSE;
112
static Bool noCursor = FALSE;
113
char *desktopName = "x11";
114
115
char rfbThisHost[256];
116
117
Atom VNC_LAST_CLIENT_ID;
118
Atom VNC_CONNECT;
119
120
#if 0
121
static HWEventQueueType alwaysCheckForInput[2] = { 0, 1 };
122
static HWEventQueueType *mieqCheckForInput[2];
123
#endif
124
125
static char primaryOrder[4] = "";
126
static int redBits, greenBits, blueBits;
127
128
static Bool rfbScreenInit(int index, ScreenPtr pScreen, int argc,
129
			  char **argv);
130
static int rfbKeybdProc(DeviceIntPtr pDevice, int onoff);
131
static int rfbMouseProc(DeviceIntPtr pDevice, int onoff);
132
static Bool CheckDisplayNumber(int n);
133
134
static Bool rfbAlwaysTrue(void);
135
static unsigned char *rfbAllocateFramebufferMemory(rfbScreenInfoPtr prfb);
136
static Bool rfbCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y);
137
static void rfbCrossScreen(ScreenPtr pScreen, Bool entering);
138
139
140
141
static void
142
PointerWarpCursor(ScreenPtr pScreen, int x, int y)
143
{
144
#if 0
145
   DeviceIntPtr pDev = NULL;
146
   miPointerSetPosition(pDev, &x, &y, GetTimeInMillis());
147
#endif
148
}
149
150
151
static miPointerScreenFuncRec rfbPointerCursorFuncs = {
152
    rfbCursorOffScreen,
153
    rfbCrossScreen,
154
    PointerWarpCursor,
155
    NULL/*dmxeqEnqueue*/,
156
    NULL/*dmxeqSwitchScreen*/
157
};
158
159
160
int inetdSock = -1;
161
static char inetdDisplayNumStr[10];
162
163
164
void
165
DDXRingBell(int volume, int pitch, int duration)
166
{
167
   /* NO-OP - stub to solve link problem */
168
}
169
170
171
/*
172
 * ddxProcessArgument is our first entry point and will be called at the
173
 * very start for each argument.  It is not called again on server reset.
174
 */
175
176
int
177
ddxProcessArgument (argc, argv, i)
178
    int argc;
179
    char *argv[];
180
    int i;
181
{
182
    VNCSCREENPTR(screenInfo.screens[i]);
183
    static Bool firstTime = TRUE;
184
185
    if (firstTime)
186
    {
187
	pVNC->width  = RFB_DEFAULT_WIDTH;
188
	pVNC->height = RFB_DEFAULT_HEIGHT;
189
	pVNC->depth  = RFB_DEFAULT_DEPTH;
190
	pVNC->blackPixel = RFB_DEFAULT_BLACKPIXEL;
191
	pVNC->whitePixel = RFB_DEFAULT_WHITEPIXEL;
192
	pVNC->pfbMemory = NULL;
193
    	pVNC->httpPort = 0;
194
    	pVNC->httpDir = NULL;
195
        pVNC->rfbAuthPasswdFile = NULL;
196
        pVNC->udpPort = 0;
197
    	pVNC->rfbPort = 0;
198
    	pVNC->rdpPort = 3389;
199
	noCursor = FALSE;
200
  	pVNC->loginAuthEnabled = FALSE;
201
	pVNC->rfbAlwaysShared = FALSE;
202
	pVNC->rfbNeverShared = FALSE;
203
	pVNC->rfbDontDisconnect = FALSE;
204
	pVNC->rfbViewOnly = FALSE;
205
206
	gethostname(rfbThisHost, 255);
207
	pVNC->interface.s_addr = htonl (INADDR_ANY);
208
	firstTime = FALSE;
209
    }
210
211
    if (strcmp (argv[i], "-geometry") == 0)	/* -geometry WxH */
212
    {
213
	if (i + 1 >= argc) UseMsg();
214
	if (sscanf(argv[i+1],"%dx%d",
215
		   &pVNC->width,&pVNC->height) != 2) {
216
	    ErrorF("Invalid geometry %s\n", argv[i+1]);
217
	    UseMsg();
218
	}
219
#ifdef CORBA
220
	screenWidth= pVNC->width;
221
	screenHeight= pVNC->height;
222
#endif
223
	return 2;
224
    }
225
226
    if (strcmp (argv[i], "-depth") == 0)	/* -depth D */
227
    {
228
	if (i + 1 >= argc) UseMsg();
229
	pVNC->depth = atoi(argv[i+1]);
230
#ifdef CORBA
231
	screenDepth= pVNC->depth;
232
#endif
233
	return 2;
234
    }
235
236
    if (strcmp (argv[i], "-pixelformat") == 0) {
237
	if (i + 1 >= argc) UseMsg();
238
	if (sscanf(argv[i+1], "%3s", primaryOrder) < 1) {
239
	    ErrorF("Invalid pixel format %s\n", argv[i+1]);
240
	    UseMsg();
241
	}
242
243
	return 2;
244
    }
245
246
    if (strcmp (argv[i], "-blackpixel") == 0) {	/* -blackpixel n */
247
	if (i + 1 >= argc) UseMsg();
248
	pVNC->blackPixel = atoi(argv[i+1]);
249
	return 2;
250
    }
251
252
    if (strcmp (argv[i], "-whitepixel") == 0) {	/* -whitepixel n */
253
	if (i + 1 >= argc) UseMsg();
254
	pVNC->whitePixel = atoi(argv[i+1]);
255
	return 2;
256
    }
257
258
    if (strcmp(argv[i], "-udpinputport") == 0) { /* -udpinputport port */
259
	if (i + 1 >= argc) UseMsg();
260
	pVNC->udpPort = atoi(argv[i+1]);
261
	return 2;
262
    }
263
264
    if (strcmp(argv[i], "-rfbport") == 0) {	/* -rfbport port */
265
	if (i + 1 >= argc) UseMsg();
266
	pVNC->rfbPort = atoi(argv[i+1]);
267
	return 2;
268
    }
269
270
    if (strcmp(argv[i], "-rfbwait") == 0) {	/* -rfbwait ms */
271
	if (i + 1 >= argc) UseMsg();
272
	rfbMaxClientWait = atoi(argv[i+1]);
273
	return 2;
274
    }
275
276
    if (strcmp(argv[i], "-nocursor") == 0) {
277
	noCursor = TRUE;
278
	return 1;
279
    }
280
281
    if (strcmp(argv[i], "-rfbauth") == 0) {	/* -rfbauth passwd-file */
282
	if (i + 1 >= argc) UseMsg();
283
	pVNC->rfbAuthPasswdFile = argv[i+1];
284
	return 2;
285
    }
286
287
    if (strcmp(argv[i], "-loginauth") == 0) {
288
	if (geteuid() == 0) {
289
	    /* Only when run as root! */
290
	    pVNC->loginAuthEnabled = TRUE;
291
	}
292
	return 1;
293
    }
294
295
    if (strcmp(argv[i], "-httpd") == 0) {
296
	if (i + 1 >= argc) UseMsg();
297
	pVNC->httpDir = argv[i+1];
298
	return 2;
299
    }
300
301
    if (strcmp(argv[i], "-httpport") == 0) {
302
	if (i + 1 >= argc) UseMsg();
303
	pVNC->httpPort = atoi(argv[i+1]);
304
	return 2;
305
    }
306
307
    if (strcmp(argv[i], "-deferupdate") == 0) {	/* -deferupdate ms */
308
	if (i + 1 >= argc) UseMsg();
309
	rfbDeferUpdateTime = atoi(argv[i+1]);
310
	return 2;
311
    }
312
313
    if (strcmp(argv[i], "-economictranslate") == 0) {
314
	rfbEconomicTranslate = TRUE;
315
	return 1;
316
    }
317
318
    if (strcmp(argv[i], "-lazytight") == 0) {
319
	rfbTightDisableGradient = TRUE;
320
	return 1;
321
    }
322
323
    if (strcmp(argv[i], "-desktop") == 0) {	/* -desktop desktop-name */
324
	if (i + 1 >= argc) UseMsg();
325
	desktopName = argv[i+1];
326
	return 2;
327
    }
328
329
#if 0 /* not deemed useful on standalone server - leave for completeness */
330
    if (strcmp(argv[i], "-useraccept") == 0) {
331
	pVNC->rfbUserAccept = TRUE;
332
	return 1;
333
    }
334
#endif
335
336
    if (strcmp(argv[i], "-alwaysshared") == 0) {
337
	pVNC->rfbAlwaysShared = TRUE;
338
	return 1;
339
    }
340
341
    if (strcmp(argv[i], "-nevershared") == 0) {
342
	pVNC->rfbNeverShared = TRUE;
343
	return 1;
344
    }
345
346
    if (strcmp(argv[i], "-dontdisconnect") == 0) {
347
	pVNC->rfbDontDisconnect = TRUE;
348
	return 1;
349
    }
350
351
    /* Run server in view-only mode - Ehud Karni SW */
352
    if (strcmp(argv[i], "-viewonly") == 0) {
353
	pVNC->rfbViewOnly = TRUE;
354
	return 1;
355
    }
356
357
    if (strcmp(argv[i], "-localhost") == 0) {
358
	pVNC->interface.s_addr = htonl (INADDR_LOOPBACK);
359
	return 1;
360
    }
361
362
    if (strcmp(argv[i], "-interface") == 0) {	/* -interface ipaddr */
363
	struct in_addr got;
364
	unsigned long octet;
365
	char *p, *end;
366
	int q;
367
	got.s_addr = 0;
368
	if (i + 1 >= argc) {
369
	    UseMsg();
370
	    return 2;
371
	}
372
	if (pVNC->interface.s_addr != htonl (INADDR_ANY)) {
373
	    /* Already set (-localhost?). */
374
	    return 2;
375
	}
376
	p = argv[i + 1];
377
	for (q = 0; q < 4; q++) {
378
	    octet = strtoul (p, &end, 10);
379
	    if (p == end || octet > 255) {
380
		UseMsg ();
381
		return 2;
382
	    }
383
	    if ((q < 3 && *end != '.') ||
384
	        (q == 3 && *end != '\0')) {
385
		UseMsg ();
386
		return 2;
387
	    }
388
	    got.s_addr = (got.s_addr << 8) | octet;
389
	    p = end + 1;
390
	}
391
	pVNC->interface.s_addr = htonl (got.s_addr);
392
	return 2;
393
    }
394
395
    if (strcmp(argv[i], "-inetd") == 0) {	/* -inetd */ 
396
	int n;
397
	for (n = 1; n < 100; n++) {
398
	    if (CheckDisplayNumber(n))
399
		break;
400
	}
401
402
	if (n >= 100)
403
	    FatalError("-inetd: couldn't find free display number");
404
405
	sprintf(inetdDisplayNumStr, "%d", n);
406
	display = inetdDisplayNumStr;
407
408
	/* fds 0, 1 and 2 (stdin, out and err) are all the same socket to the
409
           RFB client.  OsInit() closes stdout and stdin, and we don't want
410
           stderr to go to the RFB client, so make the client socket 3 and
411
           close stderr.  OsInit() will redirect stderr logging to an
412
           appropriate log file or /dev/null if that doesn't work. */
413
414
	dup2(0,3);
415
	inetdSock = 3;
416
	close(2);
417
418
	return 1;
419
    }
420
421
    if (strcmp(argv[i], "-version") == 0) {
422
	ErrorF("Xvnc version %s\n", XVNCRELEASE);
423
	exit(0);
424
    }
425
426
    if (inetdSock != -1 && argv[i][0] == ':') {
427
	FatalError("can't specify both -inetd and :displaynumber");
428
    }
429
430
    return 0;
431
}
432
433
434
/*
435
 * InitOutput is called every time the server resets.  It should call
436
 * AddScreen for each screen (FIXME - but we only ever have one), 
437
 * and in turn this will call rfbScreenInit.
438
 */
439
440
/* Common pixmap formats */
441
442
static PixmapFormatRec formats[MAXFORMATS] = {
443
	{ 1,	1,	BITMAP_SCANLINE_PAD },
444
	{ 4,	8,	BITMAP_SCANLINE_PAD },
445
	{ 8,	8,	BITMAP_SCANLINE_PAD },
446
	{ 15,	16,	BITMAP_SCANLINE_PAD },
447
	{ 16,	16,	BITMAP_SCANLINE_PAD },
448
	{ 24,	32,	BITMAP_SCANLINE_PAD },
449
#ifdef RENDER
450
	{ 32,	32,	BITMAP_SCANLINE_PAD },
451
#endif
452
};
453
#ifdef RENDER
454
static int numFormats = 7;
455
#else
456
static int numFormats = 6;
457
#endif
458
459
void
460
InitOutput(screenInfo, argc, argv)
461
    ScreenInfo *screenInfo;
462
    int argc;
463
    char **argv;
464
{
465
    int i;
466
    initOutputCalled = TRUE;
467
468
    rfbLog("Xvnc version %s\n", XVNCRELEASE);
469
    rfbLog("Copyright (C) 2001-2004 Alan Hourihane.\n");
470
    rfbLog("Copyright (C) 2000-2004 Constantin Kaplinsky\n");
471
    rfbLog("Copyright (C) 1999 AT&T Laboratories Cambridge\n");
472
    rfbLog("All Rights Reserved.\n");
473
    rfbLog("See http://www.tightvnc.com/ for information on TightVNC\n");
474
    rfbLog("See http://xf4vnc.sf.net for xf4vnc-specific information\n");
475
    rfbLog("Desktop name '%s' (%s:%s)\n",desktopName,rfbThisHost,display);
476
    rfbLog("Protocol versions supported: %d.%d, %d.%d\n",
477
	   rfbProtocolMajorVersion, rfbProtocolMinorVersion,
478
	   rfbProtocolMajorVersion, rfbProtocolFallbackMinorVersion);
479
480
    VNC_LAST_CLIENT_ID = MakeAtom("VNC_LAST_CLIENT_ID",
481
				  strlen("VNC_LAST_CLIENT_ID"), TRUE);
482
    VNC_CONNECT = MakeAtom("VNC_CONNECT", strlen("VNC_CONNECT"), TRUE);
483
484
    /* initialize pixmap formats */
485
486
    screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
487
    screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
488
    screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
489
    screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
490
    screenInfo->numPixmapFormats = numFormats;
491
    for (i = 0; i < numFormats; i++)
492
    	screenInfo->formats[i] = formats[i];
493
494
    rfbGCIndex = AllocateGCPrivateIndex();
495
    if (rfbGCIndex < 0) {
496
	FatalError("InitOutput: AllocateGCPrivateIndex failed\n");
497
    }
498
499
    /* initialize screen */
500
501
    if (AddScreen(rfbScreenInit, argc, argv) == -1) {
502
	FatalError("Couldn't add screen");
503
    }
504
505
#ifdef CORBA
506
    initialiseCORBA(argc, argv, desktopName);
507
#endif
508
}
509
510
static void
511
rfbWakeupHandler (
512
    int 	i,	
513
    pointer     blockData,
514
    unsigned long err,
515
    pointer     pReadmask
516
){
517
    ScreenPtr      pScreen = screenInfo.screens[i];
518
    VNCSCREENPTR(pScreen);
519
    int e = (int)err;
520
521
    if (e < 0)
522
	goto SKIPME;
523
	
524
    rfbRootPropertyChange(pScreen);
525
526
#if XFREE86VNC
527
    if (pScrn->vtSema) {
528
    	rfbCheckFds(pScreen);
529
    	httpCheckFds(pScreen);
530
#if 0
531
	rdpCheckFds(pScreen);
532
#endif
533
#ifdef CORBA
534
    	corbaCheckFds();
535
#endif
536
    } else {
537
    	rfbCheckFds(pScreen);
538
#if 0
539
	rdpCheckFds(pScreen);
540
#endif
541
    }
542
#else
543
    rfbCheckFds(pScreen);
544
    httpCheckFds(pScreen);
545
#if 0
546
    rdpCheckFds(pScreen);
547
#endif
548
#ifdef CORBA
549
    corbaCheckFds();
550
#endif
551
#endif
552
553
SKIPME:
554
555
    pScreen->WakeupHandler = pVNC->WakeupHandler;
556
    (*pScreen->WakeupHandler) (i, blockData, err, pReadmask);
557
    pScreen->WakeupHandler = rfbWakeupHandler;
558
}
559
560
static Bool
561
rfbScreenInit(index, pScreen, argc, argv)
562
    int index;
563
    ScreenPtr pScreen;
564
    int argc;
565
    char ** argv;
566
{
567
    rfbScreenInfoPtr prfb = &rfbScreen;
568
    int dpix = 75, dpiy = 75;
569
    int ret;
570
    unsigned char *pbits;
571
    VisualPtr vis;
572
#ifdef RENDER
573
    PictureScreenPtr	ps;
574
#endif
575
576
    if (VNCGeneration != serverGeneration) {
577
	VncExtensionInit();
578
	VNCGeneration = serverGeneration;
579
    }
580
581
    if (monitorResolution != 0) {
582
	dpix = monitorResolution;
583
	dpiy = monitorResolution;
584
    }
585
586
    prfb->rfbAuthTries = 0;
587
    prfb->rfbAuthTooManyTries = FALSE;
588
    prfb->rfbUserAccept = FALSE;
589
    prfb->udpSockConnected = FALSE;
590
    prfb->timer = NULL;
591
    prfb->httpListenSock = -1;
592
    prfb->httpSock = -1;
593
    prfb->rfbListenSock = -1;
594
    prfb->rdpListenSock = -1;
595
    prfb->paddedWidthInBytes = PixmapBytePad(prfb->width, prfb->depth);
596
    prfb->bitsPerPixel = rfbBitsPerPixel(prfb->depth);
597
    pbits = rfbAllocateFramebufferMemory(prfb);
598
    if (!pbits) return FALSE;
599
600
    miClearVisualTypes();
601
602
    if (defaultColorVisualClass == -1)
603
    	defaultColorVisualClass = TrueColor;
604
605
    if (!miSetVisualTypes(prfb->depth, miGetDefaultVisualMask(prfb->depth), 8,
606
						defaultColorVisualClass) )
607
	return FALSE;
608
609
    miSetPixmapDepths();
610
611
    switch (prfb->bitsPerPixel)
612
    {
613
    case 8:
614
	ret = fbScreenInit(pScreen, pbits, prfb->width, prfb->height,
615
			    dpix, dpiy, prfb->paddedWidthInBytes, 8);
616
	break;
617
    case 16:
618
	ret = fbScreenInit(pScreen, pbits, prfb->width, prfb->height,
619
			      dpix, dpiy, prfb->paddedWidthInBytes / 2, 16);
620
	if (prfb->depth == 15) {
621
  	    blueBits = 5; greenBits = 5; redBits = 5;
622
	} else {
623
	    blueBits = 5; greenBits = 6; redBits = 5;
624
	}
625
	break;
626
    case 32:
627
	ret = fbScreenInit(pScreen, pbits, prfb->width, prfb->height,
628
			      dpix, dpiy, prfb->paddedWidthInBytes / 4, 32);
629
	blueBits = 8; greenBits = 8; redBits = 8;
630
	break;
631
    default:
632
	return FALSE;
633
    }
634
635
    if (!ret) return FALSE;
636
637
    miInitializeBackingStore(pScreen);
638
639
    if (prfb->bitsPerPixel > 8) {
640
    	if (strcasecmp(primaryOrder, "bgr") == 0) {
641
	    rfbLog("BGR format %d %d %d\n", blueBits, greenBits, redBits);
642
            vis = pScreen->visuals + pScreen->numVisuals;
643
            while (--vis >= pScreen->visuals) {
644
	    	if ((vis->class | DynamicClass) == DirectColor) {
645
		    vis->offsetRed = 0;
646
		    vis->redMask = (1 << redBits) - 1;
647
		    vis->offsetGreen = redBits;
648
		    vis->greenMask = ((1 << greenBits) - 1) << vis->offsetGreen;
649
		    vis->offsetBlue = redBits + greenBits;
650
		    vis->blueMask = ((1 << blueBits) - 1) << vis->offsetBlue;
651
	    	}
652
	    }
653
    	} else {
654
	    rfbLog("RGB format %d %d %d\n", blueBits, greenBits, redBits);
655
       	    vis = pScreen->visuals + pScreen->numVisuals;
656
            while (--vis >= pScreen->visuals) {
657
	    	if ((vis->class | DynamicClass) == DirectColor) {
658
		    vis->offsetBlue = 0;
659
		    vis->blueMask = (1 << blueBits) - 1;
660
		    vis->offsetGreen = blueBits;
661
		    vis->greenMask = ((1 << greenBits) - 1) << vis->offsetGreen;
662
		    vis->offsetRed = blueBits + greenBits;
663
		    vis->redMask = ((1 << redBits) - 1) << vis->offsetRed;
664
	    	}
665
	    }
666
    	}
667
    }
668
669
    if (prfb->bitsPerPixel > 4)
670
	fbPictureInit(pScreen, 0, 0);
671
672
    if (!AllocateGCPrivate(pScreen, rfbGCIndex, sizeof(rfbGCRec))) {
673
	FatalError("rfbScreenInit: AllocateGCPrivate failed\n");
674
    }
675
676
    prfb->cursorIsDrawn = FALSE;
677
    prfb->dontSendFramebufferUpdate = FALSE;
678
679
    prfb->CloseScreen = pScreen->CloseScreen;
680
    prfb->WakeupHandler = pScreen->WakeupHandler;
681
    prfb->CreateGC = pScreen->CreateGC;
682
    prfb->PaintWindowBackground = pScreen->PaintWindowBackground;
683
    prfb->PaintWindowBorder = pScreen->PaintWindowBorder;
684
    prfb->CopyWindow = pScreen->CopyWindow;
685
    prfb->ClearToBackground = pScreen->ClearToBackground;
686
    prfb->RestoreAreas = pScreen->RestoreAreas;
687
#ifdef CHROMIUM
688
    prfb->RealizeWindow = pScreen->RealizeWindow;
689
    prfb->UnrealizeWindow = pScreen->UnrealizeWindow;
690
    prfb->DestroyWindow = pScreen->DestroyWindow;
691
    prfb->PositionWindow = pScreen->PositionWindow;
692
    prfb->ResizeWindow = pScreen->ResizeWindow;
693
    prfb->ClipNotify = pScreen->ClipNotify;
694
#endif
695
#ifdef RENDER
696
    ps = GetPictureScreenIfSet(pScreen);
697
    if (ps)
698
    	prfb->Composite = ps->Composite;
699
#endif
700
    pScreen->CloseScreen = rfbCloseScreen;
701
    pScreen->WakeupHandler = rfbWakeupHandler;
702
    pScreen->CreateGC = rfbCreateGC;
703
    pScreen->PaintWindowBackground = rfbPaintWindowBackground;
704
    pScreen->PaintWindowBorder = rfbPaintWindowBorder;
705
    pScreen->CopyWindow = rfbCopyWindow;
706
    pScreen->ClearToBackground = rfbClearToBackground;
707
    pScreen->RestoreAreas = rfbRestoreAreas;
708
#ifdef CHROMIUM
709
    pScreen->RealizeWindow = rfbRealizeWindow;
710
    pScreen->UnrealizeWindow = rfbUnrealizeWindow;
711
    pScreen->DestroyWindow = rfbDestroyWindow;
712
    pScreen->PositionWindow = rfbPositionWindow;
713
    pScreen->ResizeWindow = rfbResizeWindow;
714
    pScreen->ClipNotify = rfbClipNotify;
715
#endif
716
#ifdef RENDER
717
    if (ps)
718
    	ps->Composite = rfbComposite;
719
#endif
720
721
    pScreen->InstallColormap = rfbInstallColormap;
722
    pScreen->UninstallColormap = rfbUninstallColormap;
723
    pScreen->ListInstalledColormaps = rfbListInstalledColormaps;
724
    pScreen->StoreColors = rfbStoreColors;
725
726
    pScreen->SaveScreen = (SaveScreenProcPtr)rfbAlwaysTrue;
727
728
    rfbDCInitialize(pScreen, &rfbPointerCursorFuncs);
729
730
    if (noCursor) {
731
	pScreen->DisplayCursor = (DisplayCursorProcPtr)rfbAlwaysTrue;
732
	prfb->cursorIsDrawn = TRUE;
733
    }
734
735
    pScreen->blackPixel = prfb->blackPixel;
736
    pScreen->whitePixel = prfb->whitePixel;
737
738
    prfb->rfbServerFormat.bitsPerPixel = prfb->bitsPerPixel;
739
    prfb->rfbServerFormat.depth = prfb->depth;
740
    prfb->rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest);
741
742
    /* Find the root visual and set the server format */
743
    for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++)
744
	;
745
    prfb->rfbServerFormat.trueColour = (vis->class == TrueColor);
746
747
    if ( (vis->class == TrueColor) || (vis->class == DirectColor) ) {
748
	prfb->rfbServerFormat.redMax = vis->redMask >> vis->offsetRed;
749
	prfb->rfbServerFormat.greenMax = vis->greenMask >> vis->offsetGreen;
750
	prfb->rfbServerFormat.blueMax = vis->blueMask >> vis->offsetBlue;
751
	prfb->rfbServerFormat.redShift = vis->offsetRed;
752
	prfb->rfbServerFormat.greenShift = vis->offsetGreen;
753
	prfb->rfbServerFormat.blueShift = vis->offsetBlue;
754
    } else {
755
	prfb->rfbServerFormat.redMax
756
	    = prfb->rfbServerFormat.greenMax 
757
	    = prfb->rfbServerFormat.blueMax = 0;
758
	prfb->rfbServerFormat.redShift
759
	    = prfb->rfbServerFormat.greenShift 
760
	    = prfb->rfbServerFormat.blueShift = 0;
761
    }
762
763
    ret = fbCreateDefColormap(pScreen);
764
765
    rfbInitSockets(pScreen);
766
#if 0
767
    rdpInitSockets(pScreen);
768
#endif
769
    if (inetdSock == -1)
770
	httpInitSockets(pScreen);
771
772
    return ret;
773
774
} /* end rfbScreenInit */
775
776
777
778
/*
779
 * InitInput is also called every time the server resets.  It is called after
780
 * InitOutput so we can assume that rfbInitSockets has already been called.
781
 */
782
void
783
InitInput(argc, argv)
784
    int argc;
785
    char *argv[];
786
{
787
    DeviceIntPtr p, k;
788
    k = AddInputDevice(rfbKeybdProc, TRUE);
789
    p = AddInputDevice(rfbMouseProc, TRUE);
790
    RegisterKeyboardDevice(k);
791
    RegisterPointerDevice(p);
792
793
    mieqInit();
794
795
#if 0
796
    mieqCheckForInput[0] = checkForInput[0];
797
    mieqCheckForInput[1] = checkForInput[1];
798
    SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
799
#endif
800
}
801
802
803
static int
804
rfbKeybdProc(pDevice, onoff)
805
    DeviceIntPtr pDevice;
806
    int onoff;
807
{
808
    KeySymsRec		keySyms;
809
    CARD8 		modMap[MAP_LENGTH];
810
    DevicePtr pDev = (DevicePtr)pDevice;
811
812
    switch (onoff)
813
    {
814
    case DEVICE_INIT: 
815
        vncSetKeyboardDevice(pDevice);
816
	KbdDeviceInit(pDevice, &keySyms, modMap);
817
	InitKeyboardDeviceStruct(pDev, &keySyms, modMap,
818
				 (BellProcPtr)rfbSendBell,
819
				 (KbdCtrlProcPtr)NoopDDA);
820
        break;
821
    case DEVICE_ON: 
822
	pDev->on = TRUE;
823
	KbdDeviceOn();
824
	break;
825
    case DEVICE_OFF: 
826
	pDev->on = FALSE;
827
	KbdDeviceOff();
828
	break;
829
    case DEVICE_CLOSE:
830
	if (pDev->on)
831
	    KbdDeviceOff();
832
	break;
833
    }
834
    return Success;
835
}
836
837
static int
838
rfbMouseProc(pDevice, onoff)
839
    DeviceIntPtr pDevice;
840
    int onoff;
841
{
842
    BYTE map[6];
843
    DevicePtr pDev = (DevicePtr)pDevice;
844
845
    switch (onoff)
846
    {
847
    case DEVICE_INIT:
848
	PtrDeviceInit();
849
	map[1] = 1;
850
	map[2] = 2;
851
	map[3] = 3;
852
	map[4] = 4;
853
	map[5] = 5;
854
	InitPointerDeviceStruct(pDev, map, 5,
855
                                GetMotionHistory,
856
				PtrDeviceControl,
857
                                GetMaximumEventsNum(), 2 /* numAxes */);
858
        vncSetPointerDevice(pDevice);
859
	break;
860
861
    case DEVICE_ON:
862
	pDev->on = TRUE;
863
	PtrDeviceOn(pDevice);
864
        break;
865
866
    case DEVICE_OFF:
867
	pDev->on = FALSE;
868
	PtrDeviceOff();
869
	break;
870
871
    case DEVICE_CLOSE:
872
	if (pDev->on)
873
	    PtrDeviceOff();
874
	break;
875
    }
876
    return Success;
877
}
878
879
880
Bool
881
LegalModifier(unsigned int key, DeviceIntPtr pDev)
882
{
883
    return TRUE;
884
}
885
886
887
void
888
ProcessInputEvents(void)
889
{
890
#if 0
891
    if (*mieqCheckForInput[0] != *mieqCheckForInput[1]) {
892
#endif
893
	mieqProcessInputEvents();
894
#if 0
895
    }
896
#endif
897
}
898
899
900
static Bool CheckDisplayNumber(int n)
901
{
902
    char fname[32];
903
    int sock;
904
    struct sockaddr_in addr;
905
906
    sock = socket(AF_INET, SOCK_STREAM, 0);
907
908
    memset(&addr, 0, sizeof(addr));
909
    addr.sin_family = AF_INET;
910
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
911
    addr.sin_port = htons(6000+n);
912
    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
913
	close(sock);
914
	return FALSE;
915
    }
916
    close(sock);
917
918
    sprintf(fname, "/tmp/.X%d-lock", n);
919
    if (access(fname, F_OK) == 0)
920
	return FALSE;
921
922
    sprintf(fname, "/tmp/.X11-unix/X%d", n);
923
    if (access(fname, F_OK) == 0)
924
	return FALSE;
925
926
    return TRUE;
927
}
928
929
static Bool
930
rfbAlwaysTrue(void)
931
{
932
    return TRUE;
933
}
934
935
936
static unsigned char *
937
rfbAllocateFramebufferMemory(prfb)
938
    rfbScreenInfoPtr prfb;
939
{
940
    if (prfb->pfbMemory) return prfb->pfbMemory; /* already done */
941
942
    prfb->sizeInBytes = (prfb->paddedWidthInBytes * prfb->height);
943
944
    prfb->pfbMemory = (unsigned char *)Xalloc(prfb->sizeInBytes);
945
946
    return prfb->pfbMemory;
947
}
948
949
950
static Bool
951
rfbCursorOffScreen (ppScreen, x, y)
952
    ScreenPtr   *ppScreen;
953
    int         *x, *y;
954
{
955
    return FALSE;
956
}
957
958
static void
959
rfbCrossScreen (pScreen, entering)
960
    ScreenPtr   pScreen;
961
    Bool        entering;
962
{
963
}
964
965
void
966
ddxGiveUp()
967
{
968
    Xfree(rfbScreen.pfbMemory);
969
    if (initOutputCalled) {
970
	char unixSocketName[32];
971
	sprintf(unixSocketName,"/tmp/.X11-unix/X%s",display);
972
	unlink(unixSocketName);
973
#ifdef CORBA
974
	shutdownCORBA();
975
#endif
976
    }
977
}
978
979
void
980
AbortDDX()
981
{
982
    ddxGiveUp();
983
}
984
985
void
986
OsVendorInit()
987
{
988
}
989
990
void
991
OsVendorFatalError()
992
{
993
}
994
995
#ifdef DDXTIME /* from ServerOSDefines */
996
CARD32
997
GetTimeInMillis()
998
{
999
    struct timeval  tp;
1000
1001
    X_GETTIMEOFDAY(&tp);
1002
    return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
1003
}
1004
#endif
1005
1006
void
1007
ddxUseMsg()
1008
{
1009
    ErrorF("-geometry WxH          set framebuffer width & height\n");
1010
    ErrorF("-depth D               set framebuffer depth\n");
1011
    ErrorF("-pixelformat format    set pixel format (BGRnnn or RGBnnn)\n");
1012
    ErrorF("-udpinputport port     UDP port for keyboard/pointer data\n");
1013
    ErrorF("-rfbport port          TCP port for RFB protocol\n");
1014
    ErrorF("-rfbwait time          max time in ms to wait for RFB client\n");
1015
    ErrorF("-nocursor              don't put up a cursor\n");
1016
    ErrorF("-rfbauth passwd-file   use authentication on RFB protocol\n");
1017
    ErrorF("-loginauth             use login-style Unix authentication\n");
1018
    ErrorF("-httpd dir             serve files via HTTP from here\n");
1019
    ErrorF("-httpport port         port for HTTP\n");
1020
    ErrorF("-deferupdate time      time in ms to defer updates "
1021
							     "(default 40)\n");
1022
    ErrorF("-economictranslate     less memory-hungry translation\n");
1023
    ErrorF("-lazytight             disable \"gradient\" filter in tight "
1024
								"encoding\n");
1025
    ErrorF("-desktop name          VNC desktop name (default x11)\n");
1026
    ErrorF("-alwaysshared          always treat new clients as shared\n");
1027
    ErrorF("-nevershared           never treat new clients as shared\n");
1028
    ErrorF("-dontdisconnect        don't disconnect existing clients when a "
1029
                                                             "new non-shared\n"
1030
	   "                       connection comes in (refuse new connection "
1031
								 "instead)\n");
1032
    ErrorF("-localhost             only allow connections from localhost\n"
1033
	   "			   to the vnc ports. Use -nolisten tcp to disable\n"
1034
	   "			   remote X clients as well.\n");
1035
    ErrorF("-viewonly              let clients only view the desktop\n");
1036
    ErrorF("-interface ipaddr      only bind to specified interface "
1037
								"address\n");
1038
    ErrorF("-inetd                 Xvnc is launched by inetd\n");
1039
    exit(1);
1040
}
1041
1042
1043
void ddxInitGlobals(void)
1044
{
1045
   /* dummy function called by InitGlobals in os/utils.c */
1046
}
1047
1048
1049
/*
1050
 * rfbLog prints a time-stamped message to the log file (stderr).
1051
 */
1052
1053
void rfbLog(char *format, ...)
1054
{
1055
    va_list args;
1056
    char buf[256];
1057
    time_t clock;
1058
1059
    va_start(args, format);
1060
1061
    time(&clock);
1062
    strftime(buf, 255, "%d/%m/%Y %H:%M:%S ", localtime(&clock));
1063
    fprintf(stderr, buf);
1064
1065
    vfprintf(stderr, format, args);
1066
    fflush(stderr);
1067
1068
    va_end(args);
1069
}
1070
1071
void rfbLogPerror(char *str)
1072
{
1073
    rfbLog("");
1074
    perror(str);
1075
}
(-)xorg-server-1.4.orig/hw/vnc/kbdptr.c (+458 lines)
Line 0 Link Here
1
/*
2
 * kbdptr.c - deal with keyboard and pointer device over TCP & UDP.
3
 *
4
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
5
 *
6
 */
7
8
/*
9
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
10
 *
11
 *  This is free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  This software is distributed in the hope that it will be useful,
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *  GNU General Public License for more details.
20
 *
21
 *  You should have received a copy of the GNU General Public License
22
 *  along with this software; if not, write to the Free Software
23
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
24
 *  USA.
25
 */
26
#ifdef HAVE_DIX_CONFIG_H
27
#include <dix-config.h>
28
#endif
29
30
31
#include "rfb.h"
32
#include "X11/X.h"
33
#define NEED_EVENTS
34
#include "X11/Xproto.h"
35
#include "inputstr.h"
36
#define XK_CYRILLIC
37
#include <X11/keysym.h>
38
#include <X11/Xatom.h>
39
#include "mi.h"
40
#include "mipointer.h"
41
#include "keyboard.h"
42
43
#ifdef DMXVNC
44
#include "dmxinput.h"
45
#endif
46
47
#define KEY_IS_PRESSED(keycode) \
48
    (kbdDevice->key->down[(keycode) >> 3] & (1 << ((keycode) & 7)))
49
50
static void vncXConvertCase(KeySym sym, KeySym *lower, KeySym *upper);
51
52
static DeviceIntPtr ptrDevice = NULL, kbdDevice = NULL;
53
54
55
void
56
vncSetKeyboardDevice(DeviceIntPtr kbd)
57
{
58
   if (kbdDevice && kbd)
59
      return; /* set once */
60
   kbdDevice = kbd;
61
}
62
63
64
void
65
vncSetPointerDevice(DeviceIntPtr ptr)
66
{
67
   if (ptrDevice && ptr)
68
      return; /* set once */
69
   ptrDevice = ptr;
70
}
71
72
73
#ifndef DMXVNC
74
static void
75
EnqueueMotion(DeviceIntPtr ptrDev, int x, int y)
76
{
77
   xEvent *events = (xEvent*) calloc(sizeof(xEvent),  GetMaximumEventsNum());
78
   int detail = 0, valuators[2], nevents, i;
79
   valuators[0] = x;
80
   valuators[1] = y;
81
   if (!ptrDev) {
82
      ErrorF("VNC: In EnqueueMotion() ptrDev=NULL\n");
83
      return;
84
   }
85
   nevents = GetPointerEvents(events, ptrDev, MotionNotify, detail,
86
                              POINTER_ABSOLUTE, 0, 2, valuators);
87
   for (i = 0; i < nevents; i++)
88
      mieqEnqueue(ptrDev, events + i);
89
   free(events);
90
}
91
#endif
92
93
94
static void
95
EnqueueButton(DeviceIntPtr ptrDev, int type, int detail)
96
{
97
   xEvent *events = (xEvent*) calloc(sizeof(xEvent),  GetMaximumEventsNum());
98
   int nevents, i;
99
   if (!ptrDev) {
100
      ErrorF("VNC: In EnqueueButton() ptrDev=NULL\n");
101
      return;
102
   }
103
   nevents = GetPointerEvents(events, ptrDev, type, detail,
104
                              POINTER_ABSOLUTE, 0, 0, NULL/*valuators*/);
105
   for (i = 0; i < nevents; i++)
106
      mieqEnqueue(ptrDev, events + i);
107
   free(events);
108
}
109
110
111
static void
112
EnqueueKey(DeviceIntPtr kbdDev, int type, int detail)
113
{
114
   xEvent *events = (xEvent*) calloc(sizeof(xEvent),  GetMaximumEventsNum());
115
   int nevents, i;
116
   if (!kbdDev) {
117
      ErrorF("VNC: In EnqueueKey() kbdDev=NULL\n");
118
      return;
119
   }
120
   nevents = GetKeyboardEvents(events, kbdDev, type, detail);
121
   for (i = 0; i < nevents; i++)
122
      mieqEnqueue(kbdDev, events + i);
123
   free(events);
124
}
125
126
127
/*
128
 * Called when the rfbserver receives a rfbKeyEvent event from a client.
129
 * Put an X keyboard event into the event queue.
130
 */
131
void
132
KbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl)
133
{
134
    const int type = down ? KeyPress : KeyRelease;
135
    KeySymsPtr keySyms;
136
    int i;
137
    int keyCode = 0;
138
    int freeIndex = -1;
139
    Bool fakeShiftPress = FALSE;
140
    Bool fakeShiftLRelease = FALSE;
141
    Bool fakeShiftRRelease = FALSE;
142
    Bool shiftMustBeReleased = FALSE;
143
    Bool shiftMustBePressed = FALSE;
144
145
    if (!kbdDevice)
146
        return;
147
148
    keySyms = &kbdDevice->key->curKeySyms;
149
150
#ifdef CORBA
151
    if (cl) {
152
	CARD32 clientId = cl->sock;
153
	ChangeWindowProperty(WindowTable[0], VNC_LAST_CLIENT_ID, XA_INTEGER,
154
			     32, PropModeReplace, 1, (pointer)&clientId, TRUE);
155
    }
156
#endif
157
158
    /* NOTE: This is where it gets hairy for XFree86 servers.
159
     * I think the best way to deal with this is invent a new protocol
160
     * to send over the wire the remote keyboard type and correctly
161
     * handle that as XINPUT extension device (we're part of the way
162
     * there for that.
163
     *
164
     * Alan.
165
     */
166
#if !XFREE86VNC
167
    /* First check if it's one of our predefined keys.  If so then we can make
168
       some attempt at allowing an xmodmap inside a VNC desktop behave
169
       something like you'd expect - e.g. if keys A & B are swapped over and
170
       the VNC client sends an A, then map it to a B when generating the X
171
       event.  We don't attempt to do this for keycodes which we make up on the
172
       fly because it's too hard... */
173
174
    for (i = 0; i < N_PREDEFINED_KEYS * GLYPHS_PER_KEY; i++) {
175
	if (keySym == map[i]) {
176
	    keyCode = MIN_KEY_CODE + i / GLYPHS_PER_KEY;
177
178
	    if (map[(i/GLYPHS_PER_KEY) * GLYPHS_PER_KEY + 1] != NoSymbol) {
179
180
		/* this keycode has more than one symbol associated with it,
181
		   so shift state is important */
182
183
		if ((i % GLYPHS_PER_KEY) == 0)
184
		    shiftMustBeReleased = TRUE;
185
		else
186
		    shiftMustBePressed = TRUE;
187
	    }
188
	    break;
189
	}
190
    }
191
#endif
192
193
    if (!keyCode) {
194
195
	/* not one of our predefined keys - see if it's in the current keyboard
196
           mapping (i.e. we've already allocated an extra keycode for it) */
197
198
	if (keySyms->mapWidth < 2) {
199
	    ErrorF("KbdAddEvent: Sanity check failed - Keyboard mapping has "
200
		   "less than 2 keysyms per keycode (KeySym 0x%x)\n", (int)keySym);
201
	    return;
202
	}
203
204
	for (i = 0; i < NO_OF_KEYS * keySyms->mapWidth; i++) {
205
	    if (keySym == keySyms->map[i]) {
206
		keyCode = MIN_KEY_CODE + i / keySyms->mapWidth;
207
208
		if (keySyms->map[(i / keySyms->mapWidth)
209
					* keySyms->mapWidth + 1] != NoSymbol) {
210
211
		    /* this keycode has more than one symbol associated with
212
		       it, so shift state is important */
213
214
		    if ((i % keySyms->mapWidth) == 0)
215
			shiftMustBeReleased = TRUE;
216
		    else
217
			shiftMustBePressed = TRUE;
218
		}
219
		break;
220
	    }
221
	    if ((freeIndex == -1) && (keySyms->map[i] == NoSymbol)
222
		&& (i % keySyms->mapWidth) == 0)
223
	    {
224
		freeIndex = i;
225
	    }
226
	}
227
    }
228
229
    if (!keyCode) {
230
	KeySym lower, upper;
231
232
	/* we don't have an existing keycode - make one up on the fly and add
233
	   it to the keyboard mapping.  Thanks to Vlad Harchev for pointing
234
	   out problems with non-ascii capitalisation. */
235
236
	if (freeIndex == -1) {
237
	    ErrorF("KbdAddEvent: ignoring KeySym 0x%x - no free KeyCodes\n",
238
		   (int)keySym);
239
	    return;
240
	}
241
242
	keyCode = MIN_KEY_CODE + freeIndex / keySyms->mapWidth;
243
244
	vncXConvertCase(keySym, &lower, &upper);
245
246
	if (lower == upper) {
247
	    keySyms->map[freeIndex] = keySym;
248
249
	} else {
250
	    keySyms->map[freeIndex] = lower;
251
	    keySyms->map[freeIndex+1] = upper;
252
253
	    if (keySym == lower)
254
		shiftMustBeReleased = TRUE;
255
	    else
256
		shiftMustBePressed = TRUE;
257
	}
258
259
	SendMappingNotify(MappingKeyboard, keyCode, 1, serverClient);
260
261
	ErrorF("KbdAddEvent: unknown KeySym 0x%x - allocating KeyCode %d\n",
262
	       (int)keySym, keyCode);
263
    }
264
265
    if (down) {
266
	if (shiftMustBePressed && !(kbdDevice->key->state & ShiftMask)) {
267
	    fakeShiftPress = TRUE;
268
            EnqueueKey(kbdDevice, KeyPress, SHIFT_L_KEY_CODE);
269
	}
270
	if (shiftMustBeReleased && (kbdDevice->key->state & ShiftMask)) {
271
	    if (KEY_IS_PRESSED(SHIFT_L_KEY_CODE)) {
272
		fakeShiftLRelease = TRUE;
273
                EnqueueKey(kbdDevice, KeyRelease, SHIFT_L_KEY_CODE);
274
	    }
275
	    if (KEY_IS_PRESSED(SHIFT_R_KEY_CODE)) {
276
		fakeShiftRRelease = TRUE;
277
                EnqueueKey(kbdDevice, KeyRelease, SHIFT_R_KEY_CODE);
278
	    }
279
	}
280
    }
281
282
    EnqueueKey(kbdDevice, type, keyCode);
283
284
    if (fakeShiftPress) {
285
        EnqueueKey(kbdDevice, KeyRelease, SHIFT_L_KEY_CODE);
286
    }
287
    if (fakeShiftLRelease) {
288
        EnqueueKey(kbdDevice, KeyPress, SHIFT_L_KEY_CODE);
289
    }
290
    if (fakeShiftRRelease) {
291
        EnqueueKey(kbdDevice, KeyPress, SHIFT_R_KEY_CODE);
292
    }
293
}
294
295
296
/*
297
 * Called when the rfbserver receives a rfbPointerEvent event from a client.
298
 * Put an X mouse event into the event queue.
299
 */
300
void
301
PtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl)
302
{
303
    int i;
304
    static int oldButtonMask = 0;
305
306
#ifdef CORBA
307
    if (cl) {
308
	CARD32 clientId = cl->sock;
309
	ChangeWindowProperty(WindowTable[0], VNC_LAST_CLIENT_ID, XA_INTEGER,
310
			     32, PropModeReplace, 1, (pointer)&clientId, TRUE);
311
    }
312
#endif
313
314
#ifdef DMXVNC
315
    dmxCoreMotion(&ptrDevice->public, x, y, 0, DMX_BLOCK);
316
#else
317
    EnqueueMotion(ptrDevice, x, y );
318
#endif
319
320
    for (i = 0; i < 5; i++) {
321
	if ((buttonMask ^ oldButtonMask) & (1<<i)) {
322
            int type, detail;
323
	    if (buttonMask & (1<<i)) {
324
                type = ButtonPress;
325
		detail = i + 1;
326
	    } else {
327
                type = ButtonRelease;
328
		detail = i + 1;
329
	    }
330
            EnqueueButton(ptrDevice, type, detail);
331
	}
332
    }
333
334
    oldButtonMask = buttonMask;
335
}
336
337
void
338
KbdReleaseAllKeys(void)
339
{
340
    int i, j;
341
342
    if (!kbdDevice) 
343
	return;
344
345
    for (i = 0; i < DOWN_LENGTH; i++) {
346
	if (kbdDevice->key->down[i] != 0) {
347
	    for (j = 0; j < 8; j++) {
348
		if (kbdDevice->key->down[i] & (1 << j)) {
349
                    int detail = (i << 3) | j;
350
                    EnqueueKey(kbdDevice, KeyRelease, detail);
351
		}
352
	    }
353
	}
354
    }
355
}
356
357
358
/* copied from Xlib source */
359
360
static void vncXConvertCase(KeySym sym, KeySym *lower, KeySym *upper)
361
{
362
    *lower = sym;
363
    *upper = sym;
364
    switch(sym >> 8) {
365
    case 0: /* Latin 1 */
366
	if ((sym >= XK_A) && (sym <= XK_Z))
367
	    *lower += (XK_a - XK_A);
368
	else if ((sym >= XK_a) && (sym <= XK_z))
369
	    *upper -= (XK_a - XK_A);
370
	else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
371
	    *lower += (XK_agrave - XK_Agrave);
372
	else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
373
	    *upper -= (XK_agrave - XK_Agrave);
374
	else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
375
	    *lower += (XK_oslash - XK_Ooblique);
376
	else if ((sym >= XK_oslash) && (sym <= XK_thorn))
377
	    *upper -= (XK_oslash - XK_Ooblique);
378
	break;
379
    case 1: /* Latin 2 */
380
	/* Assume the KeySym is a legal value (ignore discontinuities) */
381
	if (sym == XK_Aogonek)
382
	    *lower = XK_aogonek;
383
	else if (sym >= XK_Lstroke && sym <= XK_Sacute)
384
	    *lower += (XK_lstroke - XK_Lstroke);
385
	else if (sym >= XK_Scaron && sym <= XK_Zacute)
386
	    *lower += (XK_scaron - XK_Scaron);
387
	else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
388
	    *lower += (XK_zcaron - XK_Zcaron);
389
	else if (sym == XK_aogonek)
390
	    *upper = XK_Aogonek;
391
	else if (sym >= XK_lstroke && sym <= XK_sacute)
392
	    *upper -= (XK_lstroke - XK_Lstroke);
393
	else if (sym >= XK_scaron && sym <= XK_zacute)
394
	    *upper -= (XK_scaron - XK_Scaron);
395
	else if (sym >= XK_zcaron && sym <= XK_zabovedot)
396
	    *upper -= (XK_zcaron - XK_Zcaron);
397
	else if (sym >= XK_Racute && sym <= XK_Tcedilla)
398
	    *lower += (XK_racute - XK_Racute);
399
	else if (sym >= XK_racute && sym <= XK_tcedilla)
400
	    *upper -= (XK_racute - XK_Racute);
401
	break;
402
    case 2: /* Latin 3 */
403
	/* Assume the KeySym is a legal value (ignore discontinuities) */
404
	if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
405
	    *lower += (XK_hstroke - XK_Hstroke);
406
	else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
407
	    *lower += (XK_gbreve - XK_Gbreve);
408
	else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
409
	    *upper -= (XK_hstroke - XK_Hstroke);
410
	else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
411
	    *upper -= (XK_gbreve - XK_Gbreve);
412
	else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
413
	    *lower += (XK_cabovedot - XK_Cabovedot);
414
	else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
415
	    *upper -= (XK_cabovedot - XK_Cabovedot);
416
	break;
417
    case 3: /* Latin 4 */
418
	/* Assume the KeySym is a legal value (ignore discontinuities) */
419
	if (sym >= XK_Rcedilla && sym <= XK_Tslash)
420
	    *lower += (XK_rcedilla - XK_Rcedilla);
421
	else if (sym >= XK_rcedilla && sym <= XK_tslash)
422
	    *upper -= (XK_rcedilla - XK_Rcedilla);
423
	else if (sym == XK_ENG)
424
	    *lower = XK_eng;
425
	else if (sym == XK_eng)
426
	    *upper = XK_ENG;
427
	else if (sym >= XK_Amacron && sym <= XK_Umacron)
428
	    *lower += (XK_amacron - XK_Amacron);
429
	else if (sym >= XK_amacron && sym <= XK_umacron)
430
	    *upper -= (XK_amacron - XK_Amacron);
431
	break;
432
    case 6: /* Cyrillic */
433
	/* Assume the KeySym is a legal value (ignore discontinuities) */
434
	if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
435
	    *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
436
	else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
437
	    *upper += (XK_Serbian_DJE - XK_Serbian_dje);
438
	else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
439
	    *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
440
	else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
441
	    *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
442
        break;
443
    case 7: /* Greek */
444
	/* Assume the KeySym is a legal value (ignore discontinuities) */
445
	if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
446
	    *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
447
	else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
448
		 sym != XK_Greek_iotaaccentdieresis &&
449
		 sym != XK_Greek_upsilonaccentdieresis)
450
	    *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
451
	else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
452
	    *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
453
	else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
454
		 sym != XK_Greek_finalsmallsigma)
455
	    *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
456
        break;
457
    }
458
}
(-)xorg-server-1.4.orig/hw/vnc/keyboard.h (+167 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2002 Alan Hourihane.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this software; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 *
19
 *  Author: Alan Hourihane <alanh@fairlite.demon.co.uk>
20
 */
21
22
#define MIN_KEY_CODE		8
23
#define MAX_KEY_CODE		255
24
#define NO_OF_KEYS		(MAX_KEY_CODE - MIN_KEY_CODE + 1)
25
#define GLYPHS_PER_KEY		4
26
27
#define CONTROL_L_KEY_CODE	(MIN_KEY_CODE + 29)
28
#define CONTROL_R_KEY_CODE	(MIN_KEY_CODE + 101)
29
#define SHIFT_L_KEY_CODE	(MIN_KEY_CODE + 42)
30
#define SHIFT_R_KEY_CODE	(MIN_KEY_CODE + 54)
31
#define META_L_KEY_CODE		(MIN_KEY_CODE + 107)
32
#define META_R_KEY_CODE		(MIN_KEY_CODE + 108)
33
#define ALT_L_KEY_CODE		(MIN_KEY_CODE + 56)
34
#define ALT_R_KEY_CODE		(MIN_KEY_CODE + 105)
35
36
static KeySym map[MAX_KEY_CODE * GLYPHS_PER_KEY] = {
37
    /* 0x00 */  NoSymbol,       NoSymbol,	NoSymbol,	NoSymbol,
38
    /* 0x01 */  XK_Escape,      NoSymbol,	NoSymbol,	NoSymbol,
39
    /* 0x02 */  XK_1,           XK_exclam,	NoSymbol,	NoSymbol,
40
    /* 0x03 */  XK_2,           XK_at,		NoSymbol,	NoSymbol,
41
    /* 0x04 */  XK_3,           XK_numbersign,	NoSymbol,	NoSymbol,
42
    /* 0x05 */  XK_4,           XK_dollar,	NoSymbol,	NoSymbol,
43
    /* 0x06 */  XK_5,           XK_percent,	NoSymbol,	NoSymbol,
44
    /* 0x07 */  XK_6,           XK_asciicircum,	NoSymbol,	NoSymbol,
45
    /* 0x08 */  XK_7,           XK_ampersand,	NoSymbol,	NoSymbol,
46
    /* 0x09 */  XK_8,           XK_asterisk,	NoSymbol,	NoSymbol,
47
    /* 0x0a */  XK_9,           XK_parenleft,	NoSymbol,	NoSymbol,
48
    /* 0x0b */  XK_0,           XK_parenright,	NoSymbol,	NoSymbol,
49
    /* 0x0c */  XK_minus,       XK_underscore,	NoSymbol,	NoSymbol,
50
    /* 0x0d */  XK_equal,       XK_plus,	NoSymbol,	NoSymbol,
51
    /* 0x0e */  XK_BackSpace,   NoSymbol,	NoSymbol,	NoSymbol,
52
    /* 0x0f */  XK_Tab,         XK_ISO_Left_Tab,NoSymbol,	NoSymbol,
53
    /* 0x10 */  XK_q,           XK_Q,		NoSymbol,	NoSymbol,
54
    /* 0x11 */  XK_w,           XK_W,		NoSymbol,	NoSymbol,
55
    /* 0x12 */  XK_e,           XK_E,		NoSymbol,	NoSymbol,
56
    /* 0x13 */  XK_r,           XK_R,		NoSymbol,	NoSymbol,
57
    /* 0x14 */  XK_t,           XK_T,		NoSymbol,	NoSymbol,
58
    /* 0x15 */  XK_y,           XK_Y,		NoSymbol,	NoSymbol,
59
    /* 0x16 */  XK_u,           XK_U,		NoSymbol,	NoSymbol,
60
    /* 0x17 */  XK_i,           XK_I,		NoSymbol,	NoSymbol,
61
    /* 0x18 */  XK_o,           XK_O,		NoSymbol,	NoSymbol,
62
    /* 0x19 */  XK_p,           XK_P,		NoSymbol,	NoSymbol,
63
    /* 0x1a */  XK_bracketleft, XK_braceleft,	NoSymbol,	NoSymbol,
64
    /* 0x1b */  XK_bracketright,XK_braceright,	NoSymbol,	NoSymbol,
65
    /* 0x1c */  XK_Return,      NoSymbol,	NoSymbol,	NoSymbol,
66
    /* 0x1d */  XK_Control_L,   NoSymbol,	NoSymbol,	NoSymbol,
67
    /* 0x1e */  XK_a,           XK_A,		NoSymbol,	NoSymbol,
68
    /* 0x1f */  XK_s,           XK_S,		NoSymbol,	NoSymbol,
69
    /* 0x20 */  XK_d,           XK_D,		NoSymbol,	NoSymbol,
70
    /* 0x21 */  XK_f,           XK_F,		NoSymbol,	NoSymbol,
71
    /* 0x22 */  XK_g,           XK_G,		NoSymbol,	NoSymbol,
72
    /* 0x23 */  XK_h,           XK_H,		NoSymbol,	NoSymbol,
73
    /* 0x24 */  XK_j,           XK_J,		NoSymbol,	NoSymbol,
74
    /* 0x25 */  XK_k,           XK_K,		NoSymbol,	NoSymbol,
75
    /* 0x26 */  XK_l,           XK_L,		NoSymbol,	NoSymbol,
76
    /* 0x27 */  XK_semicolon,   XK_colon,	NoSymbol,	NoSymbol,
77
    /* 0x28 */  XK_quoteright,  XK_quotedbl,	NoSymbol,	NoSymbol,
78
    /* 0x29 */  XK_quoteleft,	XK_asciitilde,	NoSymbol,	NoSymbol,
79
    /* 0x2a */  XK_Shift_L,     NoSymbol,	NoSymbol,	NoSymbol,
80
    /* 0x2b */  XK_backslash,   XK_bar,		NoSymbol,	NoSymbol,
81
    /* 0x2c */  XK_z,           XK_Z,		NoSymbol,	NoSymbol,
82
    /* 0x2d */  XK_x,           XK_X,		NoSymbol,	NoSymbol,
83
    /* 0x2e */  XK_c,           XK_C,		NoSymbol,	NoSymbol,
84
    /* 0x2f */  XK_v,           XK_V,		NoSymbol,	NoSymbol,
85
    /* 0x30 */  XK_b,           XK_B,		NoSymbol,	NoSymbol,
86
    /* 0x31 */  XK_n,           XK_N,		NoSymbol,	NoSymbol,
87
    /* 0x32 */  XK_m,           XK_M,		NoSymbol,	NoSymbol,
88
    /* 0x33 */  XK_comma,       XK_less,	NoSymbol,	NoSymbol,
89
    /* 0x34 */  XK_period,      XK_greater,	NoSymbol,	NoSymbol,
90
    /* 0x35 */  XK_slash,       XK_question,	NoSymbol,	NoSymbol,
91
    /* 0x36 */  XK_Shift_R,     NoSymbol,	NoSymbol,	NoSymbol,
92
    /* 0x37 */  XK_KP_Multiply, NoSymbol,	NoSymbol,	NoSymbol,
93
    /* 0x38 */  XK_Alt_L,	XK_Meta_L,	NoSymbol,	NoSymbol,
94
    /* 0x39 */  XK_space,       NoSymbol,	NoSymbol,	NoSymbol,
95
    /* 0x3a */  XK_Caps_Lock,   NoSymbol,	NoSymbol,	NoSymbol,
96
    /* 0x3b */  XK_F1,          NoSymbol,	NoSymbol,	NoSymbol,
97
    /* 0x3c */  XK_F2,          NoSymbol,	NoSymbol,	NoSymbol,
98
    /* 0x3d */  XK_F3,          NoSymbol,	NoSymbol,	NoSymbol,
99
    /* 0x3e */  XK_F4,          NoSymbol,	NoSymbol,	NoSymbol,
100
    /* 0x3f */  XK_F5,          NoSymbol,	NoSymbol,	NoSymbol,
101
    /* 0x40 */  XK_F6,          NoSymbol,	NoSymbol,	NoSymbol,
102
    /* 0x41 */  XK_F7,          NoSymbol,	NoSymbol,	NoSymbol,
103
    /* 0x42 */  XK_F8,          NoSymbol,	NoSymbol,	NoSymbol,
104
    /* 0x43 */  XK_F9,          NoSymbol,	NoSymbol,	NoSymbol,
105
    /* 0x44 */  XK_F10,         NoSymbol,	NoSymbol,	NoSymbol,
106
    /* 0x45 */  XK_Num_Lock,    NoSymbol,	NoSymbol,	NoSymbol,
107
    /* 0x46 */  XK_Scroll_Lock,	NoSymbol,	NoSymbol,	NoSymbol,
108
    /* 0x47 */  XK_KP_Home,	XK_KP_7,	NoSymbol,	NoSymbol,
109
    /* 0x48 */  XK_KP_Up,	XK_KP_8,	NoSymbol,	NoSymbol,
110
    /* 0x49 */  XK_KP_Prior,	XK_KP_9,	NoSymbol,	NoSymbol,
111
    /* 0x4a */  XK_KP_Subtract, NoSymbol,	NoSymbol,	NoSymbol,
112
    /* 0x4b */  XK_KP_Left,	XK_KP_4,	NoSymbol,	NoSymbol,
113
    /* 0x4c */  XK_KP_Begin,	XK_KP_5,	NoSymbol,	NoSymbol,
114
    /* 0x4d */  XK_KP_Right,	XK_KP_6,	NoSymbol,	NoSymbol,
115
    /* 0x4e */  XK_KP_Add,      NoSymbol,	NoSymbol,	NoSymbol,
116
    /* 0x4f */  XK_KP_End,	XK_KP_1,	NoSymbol,	NoSymbol,
117
    /* 0x50 */  XK_KP_Down,	XK_KP_2,	NoSymbol,	NoSymbol,
118
    /* 0x51 */  XK_KP_Next,	XK_KP_3,	NoSymbol,	NoSymbol,
119
    /* 0x52 */  XK_KP_Insert,	XK_KP_0,	NoSymbol,	NoSymbol,
120
    /* 0x53 */  XK_KP_Delete,	XK_KP_Decimal,	NoSymbol,	NoSymbol,
121
    /* 0x54 */  XK_Sys_Req,	NoSymbol,	NoSymbol,	NoSymbol,
122
    /* 0x55 */  NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
123
    /* 0x56 */  XK_less,	XK_greater,	NoSymbol,	NoSymbol,
124
    /* 0x57 */  XK_F11,		NoSymbol,	NoSymbol,	NoSymbol,
125
    /* 0x58 */  XK_F12,		NoSymbol,	NoSymbol,	NoSymbol,
126
    /* 0x59 */  XK_Home,	NoSymbol,	NoSymbol,	NoSymbol,
127
    /* 0x5a */  XK_Up,		NoSymbol,	NoSymbol,	NoSymbol,
128
    /* 0x5b */  XK_Prior,	NoSymbol,	NoSymbol,	NoSymbol,
129
    /* 0x5c */  XK_Left,	NoSymbol,	NoSymbol,	NoSymbol,
130
    /* 0x5d */  XK_Begin,	NoSymbol,	NoSymbol,	NoSymbol,
131
    /* 0x5e */  XK_Right,	NoSymbol,	NoSymbol,	NoSymbol,
132
    /* 0x5f */  XK_End,		NoSymbol,	NoSymbol,	NoSymbol,
133
    /* 0x60 */  XK_Down,	NoSymbol,	NoSymbol,	NoSymbol,
134
    /* 0x61 */  XK_Next,	NoSymbol,	NoSymbol,	NoSymbol,
135
    /* 0x62 */  XK_Insert,	NoSymbol,	NoSymbol,	NoSymbol,
136
    /* 0x63 */  XK_Delete,	NoSymbol,	NoSymbol,	NoSymbol,
137
    /* 0x64 */  XK_KP_Enter,	NoSymbol,	NoSymbol,	NoSymbol,
138
    /* 0x65 */  XK_Control_R,	NoSymbol,	NoSymbol,	NoSymbol,
139
    /* 0x66 */  XK_Pause,	NoSymbol,	NoSymbol,	NoSymbol,
140
    /* 0x67 */  XK_Print,	NoSymbol,	NoSymbol,	NoSymbol,
141
    /* 0x68 */  XK_KP_Divide,	NoSymbol,	NoSymbol,	NoSymbol,
142
    /* 0x69 */  XK_Alt_R,	XK_Meta_R,	NoSymbol,	NoSymbol,
143
    /* 0x6a */  XK_Break,	NoSymbol,	NoSymbol,	NoSymbol,
144
    /* 0x6b */  XK_Meta_L,	NoSymbol,	NoSymbol,	NoSymbol,
145
    /* 0x6c */  XK_Meta_R,	NoSymbol,	NoSymbol,	NoSymbol,
146
    /* 0x6d */  XK_Menu,	NoSymbol,	NoSymbol,	NoSymbol,
147
    /* 0x6e */  XK_F13,		NoSymbol,	NoSymbol,	NoSymbol,
148
    /* 0x6f */  XK_F14,		NoSymbol,	NoSymbol,	NoSymbol,
149
    /* 0x70 */  XK_F15,		NoSymbol,	NoSymbol,	NoSymbol,
150
    /* 0x71 */  XK_F16,		NoSymbol,	NoSymbol,	NoSymbol,
151
    /* 0x72 */  XK_F17,		NoSymbol,	NoSymbol,	NoSymbol,
152
    /* 0x73 */  XK_backslash,	XK_underscore,	NoSymbol,	NoSymbol,
153
    /* 0x74 */  NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
154
    /* 0x75 */  NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
155
    /* 0x76 */  NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
156
    /* 0x77 */  NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
157
    /* 0x78 */  NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
158
    /* 0x79 */  XK_Henkan,	XK_Mode_switch,	NoSymbol,	NoSymbol,
159
    /* 0x7a */  NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
160
    /* 0x7b */  XK_Muhenkan,	NoSymbol,	NoSymbol,	NoSymbol,
161
    /* 0x7c */  NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
162
    /* 0x7d */  XK_backslash,	XK_bar,		NoSymbol,	NoSymbol,
163
    /* 0x7e */  NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
164
    /* 0x7f */  NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
165
};
166
167
#define N_PREDEFINED_KEYS (sizeof(map) / (sizeof(KeySym) * GLYPHS_PER_KEY))
(-)xorg-server-1.4.orig/hw/vnc/LICENCE.TXT (+340 lines)
Line 0 Link Here
1
		    GNU GENERAL PUBLIC LICENSE
2
		       Version 2, June 1991
3
4
	  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5
	 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
6
 Everyone is permitted to copy and distribute verbatim copies
7
 of this license document, but changing it is not allowed.
8
9
			    Preamble
10
11
  The licenses for most software are designed to take away your
12
freedom to share and change it.  By contrast, the GNU General Public
13
License is intended to guarantee your freedom to share and change free
14
software--to make sure the software is free for all its users.  This
15
General Public License applies to most of the Free Software
16
Foundation's software and to any other program whose authors commit to
17
using it.  (Some other Free Software Foundation software is covered by
18
the GNU Library General Public License instead.)  You can apply it to
19
your programs, too.
20
21
  When we speak of free software, we are referring to freedom, not
22
price.  Our General Public Licenses are designed to make sure that you
23
have the freedom to distribute copies of free software (and charge for
24
this service if you wish), that you receive source code or can get it
25
if you want it, that you can change the software or use pieces of it
26
in new free programs; and that you know you can do these things.
27
28
  To protect your rights, we need to make restrictions that forbid
29
anyone to deny you these rights or to ask you to surrender the rights.
30
These restrictions translate to certain responsibilities for you if you
31
distribute copies of the software, or if you modify it.
32
33
  For example, if you distribute copies of such a program, whether
34
gratis or for a fee, you must give the recipients all the rights that
35
you have.  You must make sure that they, too, receive or can get the
36
source code.  And you must show them these terms so they know their
37
rights.
38
39
  We protect your rights with two steps: (1) copyright the software, and
40
(2) offer you this license which gives you legal permission to copy,
41
distribute and/or modify the software.
42
43
  Also, for each author's protection and ours, we want to make certain
44
that everyone understands that there is no warranty for this free
45
software.  If the software is modified by someone else and passed on, we
46
want its recipients to know that what they have is not the original, so
47
that any problems introduced by others will not reflect on the original
48
authors' reputations.
49
50
  Finally, any free program is threatened constantly by software
51
patents.  We wish to avoid the danger that redistributors of a free
52
program will individually obtain patent licenses, in effect making the
53
program proprietary.  To prevent this, we have made it clear that any
54
patent must be licensed for everyone's free use or not licensed at all.
55
56
  The precise terms and conditions for copying, distribution and
57
modification follow.
58
59
		    GNU GENERAL PUBLIC LICENSE
60
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
62
  0. This License applies to any program or other work which contains
63
a notice placed by the copyright holder saying it may be distributed
64
under the terms of this General Public License.  The "Program", below,
65
refers to any such program or work, and a "work based on the Program"
66
means either the Program or any derivative work under copyright law:
67
that is to say, a work containing the Program or a portion of it,
68
either verbatim or with modifications and/or translated into another
69
language.  (Hereinafter, translation is included without limitation in
70
the term "modification".)  Each licensee is addressed as "you".
71
72
Activities other than copying, distribution and modification are not
73
covered by this License; they are outside its scope.  The act of
74
running the Program is not restricted, and the output from the Program
75
is covered only if its contents constitute a work based on the
76
Program (independent of having been made by running the Program).
77
Whether that is true depends on what the Program does.
78
79
  1. You may copy and distribute verbatim copies of the Program's
80
source code as you receive it, in any medium, provided that you
81
conspicuously and appropriately publish on each copy an appropriate
82
copyright notice and disclaimer of warranty; keep intact all the
83
notices that refer to this License and to the absence of any warranty;
84
and give any other recipients of the Program a copy of this License
85
along with the Program.
86
87
You may charge a fee for the physical act of transferring a copy, and
88
you may at your option offer warranty protection in exchange for a fee.
89
90
  2. You may modify your copy or copies of the Program or any portion
91
of it, thus forming a work based on the Program, and copy and
92
distribute such modifications or work under the terms of Section 1
93
above, provided that you also meet all of these conditions:
94
95
    a) You must cause the modified files to carry prominent notices
96
    stating that you changed the files and the date of any change.
97
98
    b) You must cause any work that you distribute or publish, that in
99
    whole or in part contains or is derived from the Program or any
100
    part thereof, to be licensed as a whole at no charge to all third
101
    parties under the terms of this License.
102
103
    c) If the modified program normally reads commands interactively
104
    when run, you must cause it, when started running for such
105
    interactive use in the most ordinary way, to print or display an
106
    announcement including an appropriate copyright notice and a
107
    notice that there is no warranty (or else, saying that you provide
108
    a warranty) and that users may redistribute the program under
109
    these conditions, and telling the user how to view a copy of this
110
    License.  (Exception: if the Program itself is interactive but
111
    does not normally print such an announcement, your work based on
112
    the Program is not required to print an announcement.)
113
114
These requirements apply to the modified work as a whole.  If
115
identifiable sections of that work are not derived from the Program,
116
and can be reasonably considered independent and separate works in
117
themselves, then this License, and its terms, do not apply to those
118
sections when you distribute them as separate works.  But when you
119
distribute the same sections as part of a whole which is a work based
120
on the Program, the distribution of the whole must be on the terms of
121
this License, whose permissions for other licensees extend to the
122
entire whole, and thus to each and every part regardless of who wrote it.
123
124
Thus, it is not the intent of this section to claim rights or contest
125
your rights to work written entirely by you; rather, the intent is to
126
exercise the right to control the distribution of derivative or
127
collective works based on the Program.
128
129
In addition, mere aggregation of another work not based on the Program
130
with the Program (or with a work based on the Program) on a volume of
131
a storage or distribution medium does not bring the other work under
132
the scope of this License.
133
134
  3. You may copy and distribute the Program (or a work based on it,
135
under Section 2) in object code or executable form under the terms of
136
Sections 1 and 2 above provided that you also do one of the following:
137
138
    a) Accompany it with the complete corresponding machine-readable
139
    source code, which must be distributed under the terms of Sections
140
    1 and 2 above on a medium customarily used for software interchange; or,
141
142
    b) Accompany it with a written offer, valid for at least three
143
    years, to give any third party, for a charge no more than your
144
    cost of physically performing source distribution, a complete
145
    machine-readable copy of the corresponding source code, to be
146
    distributed under the terms of Sections 1 and 2 above on a medium
147
    customarily used for software interchange; or,
148
149
    c) Accompany it with the information you received as to the offer
150
    to distribute corresponding source code.  (This alternative is
151
    allowed only for noncommercial distribution and only if you
152
    received the program in object code or executable form with such
153
    an offer, in accord with Subsection b above.)
154
155
The source code for a work means the preferred form of the work for
156
making modifications to it.  For an executable work, complete source
157
code means all the source code for all modules it contains, plus any
158
associated interface definition files, plus the scripts used to
159
control compilation and installation of the executable.  However, as a
160
special exception, the source code distributed need not include
161
anything that is normally distributed (in either source or binary
162
form) with the major components (compiler, kernel, and so on) of the
163
operating system on which the executable runs, unless that component
164
itself accompanies the executable.
165
166
If distribution of executable or object code is made by offering
167
access to copy from a designated place, then offering equivalent
168
access to copy the source code from the same place counts as
169
distribution of the source code, even though third parties are not
170
compelled to copy the source along with the object code.
171
172
  4. You may not copy, modify, sublicense, or distribute the Program
173
except as expressly provided under this License.  Any attempt
174
otherwise to copy, modify, sublicense or distribute the Program is
175
void, and will automatically terminate your rights under this License.
176
However, parties who have received copies, or rights, from you under
177
this License will not have their licenses terminated so long as such
178
parties remain in full compliance.
179
180
  5. You are not required to accept this License, since you have not
181
signed it.  However, nothing else grants you permission to modify or
182
distribute the Program or its derivative works.  These actions are
183
prohibited by law if you do not accept this License.  Therefore, by
184
modifying or distributing the Program (or any work based on the
185
Program), you indicate your acceptance of this License to do so, and
186
all its terms and conditions for copying, distributing or modifying
187
the Program or works based on it.
188
189
  6. Each time you redistribute the Program (or any work based on the
190
Program), the recipient automatically receives a license from the
191
original licensor to copy, distribute or modify the Program subject to
192
these terms and conditions.  You may not impose any further
193
restrictions on the recipients' exercise of the rights granted herein.
194
You are not responsible for enforcing compliance by third parties to
195
this License.
196
197
  7. If, as a consequence of a court judgment or allegation of patent
198
infringement or for any other reason (not limited to patent issues),
199
conditions are imposed on you (whether by court order, agreement or
200
otherwise) that contradict the conditions of this License, they do not
201
excuse you from the conditions of this License.  If you cannot
202
distribute so as to satisfy simultaneously your obligations under this
203
License and any other pertinent obligations, then as a consequence you
204
may not distribute the Program at all.  For example, if a patent
205
license would not permit royalty-free redistribution of the Program by
206
all those who receive copies directly or indirectly through you, then
207
the only way you could satisfy both it and this License would be to
208
refrain entirely from distribution of the Program.
209
210
If any portion of this section is held invalid or unenforceable under
211
any particular circumstance, the balance of the section is intended to
212
apply and the section as a whole is intended to apply in other
213
circumstances.
214
215
It is not the purpose of this section to induce you to infringe any
216
patents or other property right claims or to contest validity of any
217
such claims; this section has the sole purpose of protecting the
218
integrity of the free software distribution system, which is
219
implemented by public license practices.  Many people have made
220
generous contributions to the wide range of software distributed
221
through that system in reliance on consistent application of that
222
system; it is up to the author/donor to decide if he or she is willing
223
to distribute software through any other system and a licensee cannot
224
impose that choice.
225
226
This section is intended to make thoroughly clear what is believed to
227
be a consequence of the rest of this License.
228
229
  8. If the distribution and/or use of the Program is restricted in
230
certain countries either by patents or by copyrighted interfaces, the
231
original copyright holder who places the Program under this License
232
may add an explicit geographical distribution limitation excluding
233
those countries, so that distribution is permitted only in or among
234
countries not thus excluded.  In such case, this License incorporates
235
the limitation as if written in the body of this License.
236
237
  9. The Free Software Foundation may publish revised and/or new versions
238
of the General Public License from time to time.  Such new versions will
239
be similar in spirit to the present version, but may differ in detail to
240
address new problems or concerns.
241
242
Each version is given a distinguishing version number.  If the Program
243
specifies a version number of this License which applies to it and "any
244
later version", you have the option of following the terms and conditions
245
either of that version or of any later version published by the Free
246
Software Foundation.  If the Program does not specify a version number of
247
this License, you may choose any version ever published by the Free Software
248
Foundation.
249
250
  10. If you wish to incorporate parts of the Program into other free
251
programs whose distribution conditions are different, write to the author
252
to ask for permission.  For software which is copyrighted by the Free
253
Software Foundation, write to the Free Software Foundation; we sometimes
254
make exceptions for this.  Our decision will be guided by the two goals
255
of preserving the free status of all derivatives of our free software and
256
of promoting the sharing and reuse of software generally.
257
258
			    NO WARRANTY
259
260
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
262
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
266
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
267
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
REPAIR OR CORRECTION.
269
270
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
POSSIBILITY OF SUCH DAMAGES.
279
280
		     END OF TERMS AND CONDITIONS
281
282
	Appendix: How to Apply These Terms to Your New Programs
283
284
  If you develop a new program, and you want it to be of the greatest
285
possible use to the public, the best way to achieve this is to make it
286
free software which everyone can redistribute and change under these terms.
287
288
  To do so, attach the following notices to the program.  It is safest
289
to attach them to the start of each source file to most effectively
290
convey the exclusion of warranty; and each file should have at least
291
the "copyright" line and a pointer to where the full notice is found.
292
293
    <one line to give the program's name and a brief idea of what it does.>
294
    Copyright (C) 19yy  <name of author>
295
296
    This program is free software; you can redistribute it and/or modify
297
    it under the terms of the GNU General Public License as published by
298
    the Free Software Foundation; either version 2 of the License, or
299
    (at your option) any later version.
300
301
    This program is distributed in the hope that it will be useful,
302
    but WITHOUT ANY WARRANTY; without even the implied warranty of
303
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
304
    GNU General Public License for more details.
305
306
    You should have received a copy of the GNU General Public License
307
    along with this program; if not, write to the Free Software
308
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
309
    USA.
310
311
Also add information on how to contact you by electronic and paper mail.
312
313
If the program is interactive, make it output a short notice like this
314
when it starts in an interactive mode:
315
316
    Gnomovision version 69, Copyright (C) 19yy name of author
317
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318
    This is free software, and you are welcome to redistribute it
319
    under certain conditions; type `show c' for details.
320
321
The hypothetical commands `show w' and `show c' should show the appropriate
322
parts of the General Public License.  Of course, the commands you use may
323
be called something other than `show w' and `show c'; they could even be
324
mouse-clicks or menu items--whatever suits your program.
325
326
You should also get your employer (if you work as a programmer) or your
327
school, if any, to sign a "copyright disclaimer" for the program, if
328
necessary.  Here is a sample; alter the names:
329
330
  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
332
333
  <signature of Ty Coon>, 1 April 1989
334
  Ty Coon, President of Vice
335
336
This General Public License does not permit incorporating your program into
337
proprietary programs.  If your program is a subroutine library, you may
338
consider it more useful to permit linking proprietary applications with the
339
library.  If this is what you want to do, use the GNU Library General
340
Public License instead of this License.
(-)xorg-server-1.4.orig/hw/vnc/loginauth.c (+143 lines)
Line 0 Link Here
1
/*
2
 * loginauth.c - deal with login-style Unix authentication.
3
 *
4
 * This file implements the UnixLogin authentication protocol when setting up
5
 * an RFB connection.
6
 *
7
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
8
 */
9
10
/*
11
 *  Copyright (C) 2003 Constantin Kaplinsky.  All Rights Reserved.
12
 *
13
 *  This is free software; you can redistribute it and/or modify
14
 *  it under the terms of the GNU General Public License as published by
15
 *  the Free Software Foundation; either version 2 of the License, or
16
 *  (at your option) any later version.
17
 *
18
 *  This software is distributed in the hope that it will be useful,
19
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 *  GNU General Public License for more details.
22
 *
23
 *  You should have received a copy of the GNU General Public License
24
 *  along with this software; if not, write to the Free Software
25
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
26
 *  USA.
27
 */
28
#ifdef HAVE_DIX_CONFIG_H
29
#include <dix-config.h>
30
#endif
31
32
33
#ifdef linux
34
#include "/usr/include/shadow.h"
35
#endif
36
#include <stdio.h>
37
#include <stdlib.h>
38
#define _XOPEN_SOURCE
39
#include <unistd.h>
40
#include <pwd.h>
41
#include <sys/types.h>
42
#include "rfb.h"
43
44
void rfbLoginAuthProcessClientMessage(rfbClientPtr cl)
45
{
46
    int n1 = 0, n2 = 0;
47
    CARD32 loginLen, passwdLen, authResult;
48
    char *loginBuf, *passwdBuf;
49
    struct passwd *ps;
50
    char *encPasswd1, *encPasswd2;
51
    Bool ok;
52
53
    if ((n1 = ReadExact(cl->sock, (char *)&loginLen,
54
			sizeof(loginLen))) <= 0 ||
55
	(n2 = ReadExact(cl->sock, (char *)&passwdLen,
56
			sizeof(passwdLen))) <= 0) {
57
	if (n1 != 0 || n2 != 0)
58
	    rfbLogPerror("rfbLoginAuthProcessClientMessage: read");
59
	rfbCloseSock(cl->pScreen, cl->sock);
60
	return;
61
    }
62
    loginLen = Swap32IfLE(loginLen);
63
    passwdLen = Swap32IfLE(passwdLen);
64
    loginBuf = (char *)xalloc(loginLen + 1);
65
    passwdBuf = (char *)xalloc(passwdLen + 1);
66
67
    n1 = n2 = 0;
68
    if ((n1 = ReadExact(cl->sock, loginBuf, loginLen)) <= 0 ||
69
	(n2 = ReadExact(cl->sock, passwdBuf, passwdLen)) <= 0) {
70
	if (n1 != 0 || n2 != 0)
71
	    rfbLogPerror("rfbLoginAuthProcessClientMessage: read");
72
	rfbCloseSock(cl->pScreen, cl->sock);
73
	return;
74
    }
75
    loginBuf[loginLen] = '\0';
76
    passwdBuf[passwdLen] = '\0';
77
78
    encPasswd1 = encPasswd2 = NULL;
79
80
    ps = getpwnam(loginBuf);
81
    if (ps == NULL) {
82
	rfbLog("rfbLoginAuthProcessClientMessage: "
83
	       "Cannot get password file entry for \"%s\"\n", loginBuf);
84
    } else {
85
	encPasswd1 = ps->pw_passwd;
86
#ifdef linux
87
	if (strlen(ps->pw_passwd) == 1) {
88
	    struct spwd *sps;
89
90
	    sps = getspnam(loginBuf);
91
	    if (sps == NULL) {
92
		rfbLog("rfbLoginAuthProcessClientMessage:"
93
		       " getspnam() failed for user \"%s\"\n", loginBuf);
94
	    } else {
95
		encPasswd1 = sps->sp_pwdp;
96
	    }
97
	}
98
#endif
99
	encPasswd2 = (char *)crypt(passwdBuf, encPasswd1);
100
	memset(passwdBuf, 0, strlen(passwdBuf));
101
    }
102
103
    ok = FALSE;
104
    if (encPasswd1 != NULL && encPasswd2 != NULL) {
105
	if (strcmp(encPasswd1, encPasswd2) == 0)
106
	    ok = TRUE;
107
    }
108
109
    if (!ok) {
110
	rfbLog("rfbAuthProcessClientMessage: authentication failed from %s\n",
111
	       cl->host);
112
113
	if (rfbAuthConsiderBlocking(cl)) {
114
	    authResult = Swap32IfLE(rfbVncAuthTooMany);
115
	} else {
116
	    authResult = Swap32IfLE(rfbVncAuthFailed);
117
	}
118
119
	if (WriteExact(cl->sock, (char *)&authResult,
120
		       sizeof(authResult)) < 0) {
121
	    rfbLogPerror("rfbLoginAuthProcessClientMessage: write");
122
	}
123
	rfbCloseSock(cl->pScreen, cl->sock);
124
	return;
125
    }
126
127
    rfbAuthUnblock(cl);
128
129
    cl->login = strdup(loginBuf);
130
    rfbLog("Login-style authentication passed for user %s at %s\n",
131
	   cl->login, cl->host);
132
133
    authResult = Swap32IfLE(rfbVncAuthOK);
134
135
    if (WriteExact(cl->sock, (char *)&authResult, sizeof(authResult)) < 0) {
136
	rfbLogPerror("rfbLoginAuthProcessClientMessage: write");
137
	rfbCloseSock(cl->pScreen, cl->sock);
138
	return;
139
    }
140
141
    cl->state = RFB_INITIALISATION;
142
}
143
(-)xorg-server-1.4.orig/hw/vnc/Makefile.am (+54 lines)
Line 0 Link Here
1
# XXX This Makefile.am probably needs some work.
2
3
bin_PROGRAMS = Xvnc
4
5
Xvnc_SOURCES = \
6
	$(top_srcdir)/fb/fbcmap_mi.c \
7
	$(top_srcdir)/Xi/stubs.c \
8
	$(top_srcdir)/mi/miinitext.c	\
9
	auth.c \
10
	cmap.c \
11
	corre.c \
12
	cursor.c \
13
	cutpaste.c \
14
	d3des.c \
15
	dispcur.c \
16
	dpmsstubs.c \
17
	draw.c \
18
	hextile.c \
19
	httpd.c \
20
	init.c \
21
	kbdptr.c \
22
	loginauth.c \
23
	rfbkeyb.c \
24
	rfbmouse.c \
25
	rfbserver.c \
26
	rre.c \
27
	sprite.c \
28
	sockets.c \
29
	stats.c \
30
	tight.c \
31
	translate.c \
32
	vncauth.c \
33
	vncext.c \
34
	zlib.c
35
36
37
JPEG_LIBS = -ljpeg
38
CRYPT_LIBS = -lcrypt
39
FB_LIBS = ../../fb/.libs/libfb.a
40
41
AM_CFLAGS = $(DIX_CFLAGS) $(XVNC_CFLAGS) -I$(top_srcdir)/hw/dmx/vnc -DCHROMIUM=1
42
43
Xvnc_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
44
Xvnc_LDADD = \
45
             $(XORG_CORE_LIBS) \
46
             $(XVNC_LIBS) \
47
             $(JPEG_LIBS) \
48
             $(CRYPT_LIBS) \
49
             $(VNCMODULES_LIBS) \
50
             $(XSERVER_LIBS)
51
52
53
relink:
54
	rm -f Xvnc && $(MAKE) Xvnc
(-)xorg-server-1.4.orig/hw/vnc/rdp.c (+147 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2004 Alan Hourihane.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this software; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 */
19
#ifdef HAVE_DIX_CONFIG_H
20
#include <dix-config.h>
21
#endif
22
23
24
#include <sys/types.h>
25
#include <sys/socket.h>
26
#include <fcntl.h>
27
#include <errno.h>
28
#include <netinet/in.h>
29
#include <netinet/tcp.h>
30
#include "rfb.h"
31
32
typedef struct rdpClientRec {
33
	ScreenPtr pScreen;
34
} rdpClientRec, *rdpClientPtr;
35
36
typedef struct rdpInRec {
37
	char version;
38
	char pad;
39
	short length; 
40
	char hdrlen;
41
	unsigned char pdu;
42
} rdpInRec, *rdpInPtr;
43
44
static void
45
rdpCloseSock(ScreenPtr pScreen)
46
{
47
    VNCSCREENPTR(pScreen);
48
    close(pVNC->rdpListenSock);
49
    RemoveEnabledDevice(pVNC->rdpListenSock);
50
    pVNC->rdpListenSock = -1;
51
}
52
53
/*
54
 * rdpNewClient is called when a new connection has been made by whatever
55
 * means.
56
 */
57
58
static rdpClientPtr
59
rdpNewClient(ScreenPtr pScreen, int sock)
60
{
61
    rdpInRec in;
62
    rdpClientPtr cl;
63
    BoxRec box;
64
    struct sockaddr_in addr;
65
    SOCKLEN_T addrlen = sizeof(struct sockaddr_in);
66
    VNCSCREENPTR(pScreen);
67
    int i;
68
69
    cl = (rdpClientPtr)xalloc(sizeof(rdpClientRec));
70
71
    cl->pScreen = pScreen;
72
73
    in.version = 3;
74
    in.pad = 0;
75
    in.length = 0x600; /* big endian */
76
    in.hdrlen = 0x00; 
77
    in.pdu = 0xCC; 
78
79
    if (WriteExact(sock, (char *)&in, sizeof(rdpInRec)) < 0) {
80
	rfbLogPerror("rfbNewClient: write");
81
	rdpCloseSock(pScreen);
82
	return NULL;
83
    }
84
85
    return cl;
86
}
87
/*
88
 * rdpCheckFds is called from ProcessInputEvents to check for input on the
89
 * HTTP socket(s).  If there is input to process, rdpProcessInput is called.
90
 */
91
92
void
93
rdpCheckFds(ScreenPtr pScreen)
94
{
95
    VNCSCREENPTR(pScreen);
96
    int nfds;
97
    fd_set fds;
98
    struct timeval tv;
99
    struct sockaddr_in addr;
100
    int sock;
101
    const int one =1;
102
    SOCKLEN_T addrlen = sizeof(addr);
103
104
    FD_ZERO(&fds);
105
    FD_SET(pVNC->rdpListenSock, &fds);
106
    tv.tv_sec = 0;
107
    tv.tv_usec = 0;
108
    nfds = select(pVNC->rdpListenSock + 1, &fds, NULL, NULL, &tv);
109
    if (nfds == 0) {
110
	return;
111
    }
112
    if (nfds < 0) {
113
	if (errno != EINTR) 
114
		rfbLogPerror("httpCheckFds: select");
115
	return;
116
    }
117
118
    if (pVNC->rdpListenSock != -1 && FD_ISSET(pVNC->rdpListenSock, &fds)) {
119
120
	if ((sock = accept(pVNC->rdpListenSock,
121
			   (struct sockaddr *)&addr, &addrlen)) < 0) {
122
	    rfbLogPerror("rdpCheckFds: accept");
123
	    return;
124
	}
125
126
	if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
127
	    rfbLogPerror("rdpCheckFds: fcntl");
128
	    close(sock);
129
	    return;
130
	}
131
132
	if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
133
		       (char *)&one, sizeof(one)) < 0) {
134
	    rfbLogPerror("rdpCheckFds: setsockopt");
135
	    close(sock);
136
	    return;
137
	}
138
139
	rfbLog("\n");
140
141
	rfbLog("Got RDP connection from client %s\n", inet_ntoa(addr.sin_addr));
142
143
	AddEnabledDevice(sock);
144
145
	rdpNewClient(pScreen, sock);
146
    }
147
}
(-)xorg-server-1.4.orig/hw/vnc/README (+14 lines)
Line 0 Link Here
1
2
This is the directory containing the code specific to the TightVNC X server (Xvnc).
3
Note that within this directory the name RFB is still used instead of VNC.
4
5
NOTE:
6
7
The is the new XFree86 v4 architecture VNC server code.
8
9
Modified entirely by Alan Hourihane <alanh@fairlite.demon.co.uk>
10
11
For information please visit http://xf4vnc.sourceforge.net
12
13
Moved to X.org modular tree by Brian Paul.
14
(-)xorg-server-1.4.orig/hw/vnc/rfb.h (+749 lines)
Line 0 Link Here
1
/*
2
 * rfb.h - header file for RFB DDX implementation.
3
 *
4
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
5
 */
6
7
/*
8
 *  Copyright (C) 2000-2004 Const Kaplinsky.  All Rights Reserved.
9
 *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
10
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
11
 *
12
 *  This is free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 2 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  This software is distributed in the hope that it will be useful,
18
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 *  GNU General Public License for more details.
21
 *
22
 *  You should have received a copy of the GNU General Public License
23
 *  along with this software; if not, write to the Free Software
24
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
25
 *  USA.
26
 */
27
28
#ifndef RFB_H_INCLUDED
29
#define RFB_H_INCLUDED
30
31
#ifdef HAVE_DMX_CONFIG_H
32
#include "dmx-config.h"
33
#endif
34
35
#ifdef DMXVNC
36
#include <dmx.h>
37
#else
38
#include <dix-config.h>
39
#endif
40
41
#include <zlib.h>
42
#ifdef XFREE86VNC
43
#include "xf86.h"
44
#endif
45
#include "scrnintstr.h"
46
#include "colormapst.h"
47
#include "dixstruct.h"
48
#include "gcstruct.h"
49
#include "regionstr.h"
50
#include "windowstr.h"
51
#include "dixfontstr.h"
52
#include "mipointer.h"
53
#include <rfbproto.h>
54
#include <vncauth.h>
55
#define _VNC_SERVER
56
#include <X11/extensions/vnc.h>
57
#include "picturestr.h"
58
59
#if defined(sun) || defined(hpux)
60
#define SOCKLEN_T	int
61
#else
62
#define SOCKLEN_T	socklen_t
63
#endif
64
65
/* It's a good idea to keep these values a bit greater than required. */
66
#define MAX_ENCODINGS 10
67
#define MAX_SECURITY_TYPES 4
68
#define MAX_TUNNELING_CAPS 16
69
#define MAX_AUTH_CAPS 16
70
71
/* 
72
 * HTTP_BUF_SIZE for http transfers
73
 */
74
#define HTTP_BUF_SIZE 32768
75
76
/*
77
 * UPDATE_BUF_SIZE must be big enough to send at least one whole line of the
78
 * framebuffer.  So for a max screen width of say 2K with 32-bit pixels this
79
 * means 8K minimum.
80
 */
81
#define UPDATE_BUF_SIZE 30000
82
83
#if XFREE86VNC || defined(DMXVNC)
84
#include "vncint.h"
85
#define VNCSCREENPTR(ptr) \
86
	vncScreenPtr pVNC = VNCPTR(ptr)
87
#else
88
#define VNCSCREENPTR(ptr) \
89
/* Soon \
90
	rfbScreenInfoPtr pVNC = rfbScreen[ptr->myNum] \
91
*/ \
92
	rfbScreenInfoPtr pVNC = &rfbScreen
93
#endif
94
95
/*
96
 * Per-screen (framebuffer) structure.  There is only one of these, since we
97
 * don't allow the X server to have multiple screens.
98
 */
99
100
typedef struct
101
{
102
    int			rfbPort;
103
    int			rdpPort;
104
    int			udpPort;
105
    int			rfbListenSock;
106
    int			rdpListenSock;
107
    int			udpSock;
108
    int			httpPort;
109
    int			httpListenSock;
110
    int			httpSock;
111
    char *		httpDir;
112
    char		buf[HTTP_BUF_SIZE];
113
    Bool		udpSockConnected;
114
    char *		rfbAuthPasswdFile;
115
    size_t		buf_filled;
116
    int			maxFd;
117
    fd_set		allFds;
118
    Bool		noCursor;
119
    Bool		rfbAlwaysShared;
120
    Bool		rfbNeverShared;
121
    Bool		rfbDontDisconnect;
122
    Bool		rfbUserAccept;
123
    Bool		rfbViewOnly;
124
    ColormapPtr		savedColormap;
125
    ColormapPtr 	rfbInstalledColormap;
126
    rfbPixelFormat	rfbServerFormat;
127
    Bool		rfbAuthTooManyTries;
128
    int			rfbAuthTries;
129
    Bool		loginAuthEnabled;
130
    struct in_addr	interface;
131
    OsTimerPtr 		timer;
132
    unsigned char updateBuf[UPDATE_BUF_SIZE];
133
    int ublen;
134
    int width;
135
    int paddedWidthInBytes;
136
    int height;
137
    int depth;
138
    int bitsPerPixel;
139
    int sizeInBytes;
140
    unsigned char *pfbMemory;
141
    Pixel blackPixel;
142
    Pixel whitePixel;
143
144
    /* The following two members are used to minimise the amount of unnecessary
145
       drawing caused by cursor movement.  Whenever any drawing affects the
146
       part of the screen where the cursor is, the cursor is removed first and
147
       then the drawing is done (this is what the sprite routines test for).
148
       Afterwards, however, we do not replace the cursor, even when the cursor
149
       is logically being moved across the screen.  We only draw the cursor
150
       again just as we are about to send the client a framebuffer update.
151
152
       We need to be careful when removing and drawing the cursor because of
153
       their relationship with the normal drawing routines.  The drawing
154
       routines can invoke the cursor routines, but also the cursor routines
155
       themselves end up invoking drawing routines.
156
157
       Removing the cursor (rfbSpriteRemoveCursor) is eventually achieved by
158
       doing a CopyArea from a pixmap to the screen, where the pixmap contains
159
       the saved contents of the screen under the cursor.  Before doing this,
160
       however, we set cursorIsDrawn to FALSE.  Then, when CopyArea is called,
161
       it sees that cursorIsDrawn is FALSE and so doesn't feel the need to
162
       (recursively!) remove the cursor before doing it.
163
164
       Putting up the cursor (rfbSpriteRestoreCursor) involves a call to
165
       PushPixels.  While this is happening, cursorIsDrawn must be FALSE so
166
       that PushPixels doesn't think it has to remove the cursor first.
167
       Obviously cursorIsDrawn is set to TRUE afterwards.
168
169
       Another problem we face is that drawing routines sometimes cause a
170
       framebuffer update to be sent to the RFB client.  When the RFB client is
171
       already waiting for a framebuffer update and some drawing to the
172
       framebuffer then happens, the drawing routine sees that the client is
173
       ready, so it calls rfbSendFramebufferUpdate.  If the cursor is not drawn
174
       at this stage, it must be put up, and so rfbSpriteRestoreCursor is
175
       called.  However, if the original drawing routine was actually called
176
       from within rfbSpriteRestoreCursor or rfbSpriteRemoveCursor we don't
177
       want this to happen.  So both the cursor routines set
178
       dontSendFramebufferUpdate to TRUE, and all the drawing routines check
179
       this before calling rfbSendFramebufferUpdate. */
180
181
    Bool cursorIsDrawn;		    /* TRUE if the cursor is currently drawn */
182
    Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the
183
				       cursor */
184
185
    /* wrapped screen functions */
186
187
    CloseScreenProcPtr			CloseScreen;
188
    CreateGCProcPtr			CreateGC;
189
    PaintWindowBackgroundProcPtr	PaintWindowBackground;
190
    PaintWindowBorderProcPtr		PaintWindowBorder;
191
    CopyWindowProcPtr			CopyWindow;
192
    ClearToBackgroundProcPtr		ClearToBackground;
193
    RestoreAreasProcPtr			RestoreAreas;
194
    ScreenWakeupHandlerProcPtr 		WakeupHandler;
195
#ifdef CHROMIUM
196
    RealizeWindowProcPtr		RealizeWindow;
197
    UnrealizeWindowProcPtr		UnrealizeWindow;
198
    DestroyWindowProcPtr		DestroyWindow;
199
    ResizeWindowProcPtr			ResizeWindow;
200
    PositionWindowProcPtr		PositionWindow;
201
    ClipNotifyProcPtr			ClipNotify;
202
#endif
203
#ifdef RENDER
204
    CompositeProcPtr			Composite;
205
#endif
206
207
} rfbScreenInfo, *rfbScreenInfoPtr;
208
209
210
/*
211
 * rfbTranslateFnType is the type of translation functions.
212
 */
213
214
struct rfbClientRec;
215
typedef void (*rfbTranslateFnType)(ScreenPtr pScreen, 
216
				   char *table, rfbPixelFormat *in,
217
				   rfbPixelFormat *out,
218
				   unsigned char *optr,
219
				   int bytesBetweenInputLines,
220
				   int width, int height,
221
				   int x, int y);
222
223
224
/*
225
 * Per-client structure.
226
 */
227
228
typedef struct rfbClientRec {
229
    int sock;
230
    char *host;
231
    char *login;
232
233
    int protocol_minor_ver;	/* RFB protocol minor version in use. */
234
    Bool protocol_tightvnc;	/* TightVNC protocol extensions enabled */
235
236
    /* Possible client states: */
237
238
    enum {
239
	RFB_PROTOCOL_VERSION,	/* establishing protocol version */
240
        RFB_SECURITY_TYPE,	/* negotiating security (RFB v.3.7) */
241
	RFB_TUNNELING_TYPE,	/* establishing tunneling (RFB v.3.7t) */
242
	RFB_AUTH_TYPE,		/* negotiating authentication (RFB v.3.7t) */
243
	RFB_AUTHENTICATION,	/* authenticating (VNC authentication) */
244
	RFB_INITIALISATION,	/* sending initialisation messages */
245
	RFB_NORMAL		/* normal protocol messages */
246
    } state;
247
248
    Bool viewOnly;		/* Do not accept input from this client. */
249
250
    Bool reverseConnection;
251
252
    Bool readyForSetColourMapEntries;
253
254
    Bool useCopyRect;
255
    int preferredEncoding;
256
    int correMaxWidth, correMaxHeight;
257
258
    /* The list of security types sent to this client (protocol 3.7).
259
       Note that the first entry is the number of list items following. */
260
261
    CARD8 securityTypes[MAX_SECURITY_TYPES + 1];
262
263
    /* Lists of capability codes sent to clients. We remember these
264
       lists to restrict clients from choosing those tunneling and
265
       authentication types that were not advertised. */
266
267
    int nAuthCaps;
268
    CARD32 authCaps[MAX_AUTH_CAPS];
269
270
    /* This is not useful while we don't support tunneling:
271
    int nTunnelingCaps;
272
    CARD32 tunnelingCaps[MAX_TUNNELING_CAPS]; */
273
274
    /* The following member is only used during VNC authentication */
275
276
    CARD8 authChallenge[CHALLENGESIZE];
277
278
    /* The following members represent the update needed to get the client's
279
       framebuffer from its present state to the current state of our
280
       framebuffer.
281
282
       If the client does not accept CopyRect encoding then the update is
283
       simply represented as the region of the screen which has been modified
284
       (modifiedRegion).
285
286
       If the client does accept CopyRect encoding, then the update consists of
287
       two parts.  First we have a single copy from one region of the screen to
288
       another (the destination of the copy is copyRegion), and second we have
289
       the region of the screen which has been modified in some other way
290
       (modifiedRegion).
291
292
       Although the copy is of a single region, this region may have many
293
       rectangles.  When sending an update, the copyRegion is always sent
294
       before the modifiedRegion.  This is because the modifiedRegion may
295
       overlap parts of the screen which are in the source of the copy.
296
297
       In fact during normal processing, the modifiedRegion may even overlap
298
       the destination copyRegion.  Just before an update is sent we remove
299
       from the copyRegion anything in the modifiedRegion. */
300
301
    RegionRec copyRegion;	/* the destination region of the copy */
302
    int copyDX, copyDY;		/* the translation by which the copy happens */
303
304
    RegionRec modifiedRegion;	/* the region of the screen modified in any
305
				   other way */
306
307
    /* As part of the FramebufferUpdateRequest, a client can express interest
308
       in a subrectangle of the whole framebuffer.  This is stored in the
309
       requestedRegion member.  In the normal case this is the whole
310
       framebuffer if the client is ready, empty if it's not. */
311
312
    RegionRec requestedRegion;
313
314
    /* The following members represent the state of the "deferred update" timer
315
       - when the framebuffer is modified and the client is ready, in most
316
       cases it is more efficient to defer sending the update by a few
317
       milliseconds so that several changes to the framebuffer can be combined
318
       into a single update. */
319
320
    Bool deferredUpdateScheduled;
321
    OsTimerPtr deferredUpdateTimer;
322
323
    /* translateFn points to the translation function which is used to copy
324
       and translate a rectangle from the framebuffer to an output buffer. */
325
326
    rfbTranslateFnType translateFn;
327
328
    char *translateLookupTable;
329
330
    rfbPixelFormat format;
331
332
    /* statistics */
333
334
    int rfbBytesSent[MAX_ENCODINGS];
335
    int rfbRectanglesSent[MAX_ENCODINGS];
336
    int rfbLastRectMarkersSent;
337
    int rfbLastRectBytesSent;
338
    int rfbCursorShapeBytesSent;
339
    int rfbCursorShapeUpdatesSent;
340
    int rfbCursorPosBytesSent;
341
    int rfbCursorPosUpdatesSent;
342
    int rfbFramebufferUpdateMessagesSent;
343
    int rfbRawBytesEquivalent;
344
    int rfbKeyEventsRcvd;
345
    int rfbPointerEventsRcvd;
346
347
    /* zlib encoding -- necessary compression state info per client */
348
349
    struct z_stream_s compStream;
350
    Bool compStreamInited;
351
352
    CARD32 zlibCompressLevel;
353
354
    /* tight encoding -- preserve zlib streams' state for each client */
355
356
    z_stream zsStruct[4];
357
    Bool zsActive[4];
358
    int zsLevel[4];
359
    int tightCompressLevel;
360
    int tightQualityLevel;
361
362
    Bool enableLastRectEncoding;   /* client supports LastRect encoding */
363
    Bool enableCursorShapeUpdates; /* client supports cursor shape updates */
364
    Bool enableCursorPosUpdates;   /* client supports PointerPos updates */
365
#ifdef CHROMIUM
366
    Bool enableChromiumEncoding;   /* client supports Chromium encoding */
367
#endif
368
    Bool useRichCursorEncoding;    /* rfbEncodingRichCursor is preferred */
369
    Bool cursorWasChanged;         /* cursor shape update should be sent */
370
    Bool cursorWasMoved;           /* cursor position update should be sent */
371
372
    int cursorX, cursorY;          /* client's cursor position */
373
374
    struct rfbClientRec *next;
375
376
    ScreenPtr pScreen;
377
    int userAccepted;
378
379
#ifdef CHROMIUM
380
    unsigned int chromium_port;
381
    unsigned int chromium_msport;
382
#endif
383
} rfbClientRec, *rfbClientPtr;
384
385
#ifdef CHROMIUM
386
typedef struct CRWindowTable {
387
	unsigned long CRwinId;
388
	unsigned long XwinId;
389
	BoxPtr clipRects;
390
	int numRects;
391
	struct CRWindowTable *next;
392
} CRWindowTable, *CRWindowTablePtr;
393
394
extern struct CRWindowTable *windowTable;
395
#endif
396
397
/*
398
 * This macro is used to test whether there is a framebuffer update needing to
399
 * be sent to the client.
400
 */
401
402
#define FB_UPDATE_PENDING(cl)                                           \
403
    ((!(cl)->enableCursorShapeUpdates && !pVNC->cursorIsDrawn) ||   \
404
     ((cl)->enableCursorShapeUpdates && (cl)->cursorWasChanged) ||      \
405
     ((cl)->enableCursorPosUpdates && (cl)->cursorWasMoved) ||          \
406
     REGION_NOTEMPTY(((cl)->pScreen),&(cl)->copyRegion) ||                    \
407
     REGION_NOTEMPTY(((cl)->pScreen),&(cl)->modifiedRegion))
408
409
/*
410
 * This macro creates an empty region (ie. a region with no areas) if it is
411
 * given a rectangle with a width or height of zero. It appears that 
412
 * REGION_INTERSECT does not quite do the right thing with zero-width
413
 * rectangles, but it should with completely empty regions.
414
 */
415
416
#define SAFE_REGION_INIT(pscreen, preg, rect, size)          \
417
{                                                            \
418
      if ( ( (rect) ) &&                                     \
419
           ( ( (rect)->x2 == (rect)->x1 ) ||                 \
420
	     ( (rect)->y2 == (rect)->y1 ) ) ) {              \
421
	  REGION_NULL( (pscreen), (preg) ); 		     \
422
      } else {                                               \
423
	  REGION_INIT( (pscreen), (preg), (rect), (size) );  \
424
      }                                                      \
425
}
426
427
/*
428
 * An rfbGCRec is where we store the pointers to the original GC funcs and ops
429
 * which we wrap (NULL means not wrapped).
430
 */
431
432
typedef struct {
433
    GCFuncs *wrapFuncs;
434
    GCOps *wrapOps;
435
} rfbGCRec, *rfbGCPtr;
436
437
438
439
/*
440
 * Macros for endian swapping.
441
 */
442
443
#define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff))
444
445
#define Swap32(l) (((l) >> 24) | \
446
		   (((l) & 0x00ff0000) >> 8)  | \
447
		   (((l) & 0x0000ff00) << 8)  | \
448
		   ((l) << 24))
449
450
static const int rfbEndianTest = 1;
451
452
#define Swap16IfLE(s) (*(const char *)&rfbEndianTest ? Swap16(s) : (s))
453
454
#define Swap32IfLE(l) (*(const char *)&rfbEndianTest ? Swap32(l) : (l))
455
456
457
/*
458
 * Macro to fill in an rfbCapabilityInfo structure (protocol 3.130).
459
 * Normally, using macros is no good, but this macro saves us from
460
 * writing constants twice -- it constructs signature names from codes.
461
 * Note that "code_sym" argument should be a single symbol, not an expression.
462
 */
463
464
#define SetCapInfo(cap_ptr, code_sym, vendor)		\
465
{							\
466
    rfbCapabilityInfo *pcap;				\
467
    pcap = (cap_ptr);					\
468
    pcap->code = Swap32IfLE(code_sym);			\
469
    memcpy(pcap->vendorSignature, (vendor),		\
470
	   sz_rfbCapabilityInfoVendor);			\
471
    memcpy(pcap->nameSignature, sig_##code_sym,		\
472
	   sz_rfbCapabilityInfoName);			\
473
}
474
475
476
/* init.c */
477
478
extern char *desktopName;
479
extern char rfbThisHost[];
480
extern Atom VNC_LAST_CLIENT_ID;
481
482
extern rfbScreenInfo rfbScreen;
483
extern int rfbGCIndex;
484
485
extern int inetdSock;
486
487
extern int rfbBitsPerPixel(int depth);
488
extern void rfbLog(char *format, ...);
489
extern void rfbLogPerror(char *str);
490
491
492
/* sockets.c */
493
494
extern int rfbMaxClientWait;
495
496
extern Bool rfbInitSockets(ScreenPtr pScreen);
497
extern void rfbDisconnectUDPSock(ScreenPtr pScreen);
498
extern void rfbCloseSock(ScreenPtr pScreen, int sock);
499
extern void rfbCheckFds(ScreenPtr pScreen);
500
extern void rfbWaitForClient(int sock);
501
extern int rfbConnect(ScreenPtr pScreen, char *host, int port);
502
503
extern int ReadExact(int sock, char *buf, int len);
504
extern int WriteExact(int sock, char *buf, int len);
505
extern int ListenOnTCPPort(ScreenPtr pScreen, int port);
506
extern int ListenOnUDPPort(ScreenPtr pScreen, int port);
507
extern int ConnectToTcpAddr(char *host, int port);
508
509
510
/* cmap.c */
511
512
513
extern int rfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps);
514
extern void rfbInstallColormap(ColormapPtr pmap);
515
extern void rfbUninstallColormap(ColormapPtr pmap);
516
extern void rfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs);
517
518
519
/* draw.c */
520
521
extern int rfbDeferUpdateTime;
522
523
extern void
524
rfbComposite(
525
    CARD8 op,
526
    PicturePtr pSrc,
527
    PicturePtr pMask,
528
    PicturePtr pDst,
529
    INT16 xSrc,
530
    INT16 ySrc,
531
    INT16 xMask,
532
    INT16 yMask,
533
    INT16 xDst,
534
    INT16 yDst,
535
    CARD16 width,
536
    CARD16 height
537
);
538
539
extern void rfbGlyphs(
540
    CARD8 op,
541
    PicturePtr pSrc,
542
    PicturePtr pDst,
543
    PictFormatPtr maskFormat,
544
    INT16 xSrc,
545
    INT16 ySrc,
546
    int nlistInit,
547
    GlyphListPtr listInit,
548
    GlyphPtr *glyphsInit
549
);
550
extern Bool rfbCloseScreen(int,ScreenPtr);
551
extern Bool rfbCreateGC(GCPtr);
552
extern void rfbPaintWindowBackground(WindowPtr, RegionPtr, int what);
553
extern void rfbPaintWindowBorder(WindowPtr, RegionPtr, int what);
554
extern void rfbCopyWindow(WindowPtr, DDXPointRec, RegionPtr);
555
#ifdef CHROMIUM
556
extern Bool rfbRealizeWindow(WindowPtr); 
557
extern Bool rfbUnrealizeWindow(WindowPtr); 
558
extern Bool rfbDestroyWindow(WindowPtr);
559
extern void rfbResizeWindow(WindowPtr, int x, int y, unsigned int w, unsigned int h, WindowPtr pSib);
560
extern Bool rfbPositionWindow(WindowPtr, int x, int y);
561
extern void rfbClipNotify(WindowPtr, int x, int y);
562
#endif
563
extern void rfbClearToBackground(WindowPtr, int x, int y, int w,
564
				 int h, Bool generateExposures);
565
extern RegionPtr rfbRestoreAreas(WindowPtr, RegionPtr);
566
extern void rfbScheduleUpdate(ScreenPtr pScreen);
567
568
/* dispcur.c */
569
extern Bool rfbDCInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs);
570
571
572
/* cutpaste.c */
573
574
extern void rfbSetXCutText(char *str, int len);
575
extern void rfbGotXCutText(char *str, int len);
576
577
578
/* kbdptr.c */
579
580
extern Bool compatibleKbd;
581
extern unsigned char ptrAcceleration;
582
583
extern void PtrDeviceInit(void);
584
extern void PtrDeviceOn(DeviceIntPtr pDev);
585
extern void PtrDeviceOff(void);
586
extern void PtrDeviceControl(DeviceIntPtr dev, PtrCtrl *ctrl);
587
extern void PtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl);
588
589
extern void KbdDeviceInit(DeviceIntPtr pDevice, KeySymsPtr pKeySyms, CARD8 *pModMap);
590
extern void KbdDeviceOn(void);
591
extern void KbdDeviceOff(void);
592
extern void KbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl);
593
extern void KbdReleaseAllKeys(void);
594
595
extern void vncSetKeyboardDevice(DeviceIntPtr kbd);
596
extern void vncSetPointerDevice(DeviceIntPtr ptr);
597
598
599
/* rfbserver.c */
600
601
602
extern rfbClientPtr rfbClientHead;
603
extern rfbClientPtr pointerClient;
604
605
extern void rfbNewClientConnection(ScreenPtr pScreen, int sock);
606
extern rfbClientPtr rfbReverseConnection(ScreenPtr pScreen, char *host, int port);
607
extern void rfbRootPropertyChange(ScreenPtr pScreen);
608
extern void rfbClientConnectionGone(int sock);
609
extern void rfbProcessClientMessage(ScreenPtr pScreen, int sock);
610
extern void rfbClientConnFailed(rfbClientPtr cl, char *reason);
611
extern void rfbNewUDPConnection(int sock);
612
extern void rfbProcessUDPInput(ScreenPtr pScreen, int sock);
613
extern Bool rfbSendFramebufferUpdate(ScreenPtr pScreen, rfbClientPtr cl);
614
extern Bool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h);
615
extern Bool rfbSendUpdateBuf(rfbClientPtr cl);
616
extern Bool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour,
617
				       int nColours);
618
extern void rfbSendBell(void);
619
extern void rfbSendServerCutText(char *str, int len);
620
extern void rfbUserAllow(int sock, int accept);
621
extern void rfbSetClip (WindowPtr pWin, BOOL enable);
622
623
extern int GenerateVncConnectedEvent(int sock);
624
extern int GenerateVncDisconnectedEvent(int sock);
625
626
#ifdef CHROMIUM
627
extern void rfbSendChromiumWindowShow(unsigned int winid, unsigned int show);
628
extern void rfbSendChromiumWindowDestroy(unsigned int winid);
629
extern void rfbSendChromiumMoveResizeWindow(unsigned int winid, int x, int y, unsigned int w, unsigned int h);
630
extern void rfbSendChromiumClipList(unsigned int winid, BoxPtr pClipRects, int numClipRects);
631
#endif
632
633
/* translate.c */
634
635
extern Bool rfbEconomicTranslate;
636
637
extern void rfbTranslateNone(ScreenPtr pScreen, char *table, rfbPixelFormat *in,
638
			     rfbPixelFormat *out,
639
			     unsigned char *optr,
640
			     int bytesBetweenInputLines,
641
			     int width, int height,
642
			     int x, int y);
643
extern Bool rfbSetTranslateFunction(rfbClientPtr cl);
644
extern void rfbSetClientColourMaps(int firstColour, int nColours);
645
extern Bool rfbSetClientColourMap(rfbClientPtr cl, int firstColour,
646
				  int nColours);
647
648
649
/* httpd.c */
650
651
extern Bool httpInitSockets(ScreenPtr pScreen);
652
extern void httpCheckFds(ScreenPtr pScreen);
653
654
655
/* vncInit.c */
656
extern void VNCInitForDMX(void);
657
extern void rfbWakeupHandlerDMX(void);
658
659
660
/* vncext.c */
661
662
#ifdef CHROMIUM
663
extern void rfbSendChromiumStart(unsigned int ipaddress, unsigned int crServerPort, unsigned int mothershipPort);
664
extern void rfbChromiumMonitorWindowID(unsigned int cr_windowid, unsigned long windowid);
665
int GenerateVncChromiumConnectedEvent(int sock);
666
#endif
667
668
669
/* auth.c */
670
671
extern void rfbAuthNewClient(rfbClientPtr cl);
672
extern void rfbProcessClientSecurityType(rfbClientPtr cl);
673
extern void rfbProcessClientTunnelingType(rfbClientPtr cl);
674
extern void rfbProcessClientAuthType(rfbClientPtr cl);
675
extern void rfbVncAuthProcessResponse(rfbClientPtr cl);
676
677
/* Functions to prevent too many successive authentication failures */
678
extern Bool rfbAuthConsiderBlocking(rfbClientPtr cl);
679
extern void rfbAuthUnblock(rfbClientPtr cl);
680
extern Bool rfbAuthIsBlocked(rfbClientPtr cl);
681
682
/* loginauth.c */
683
684
extern void rfbLoginAuthProcessClientMessage(rfbClientPtr cl);
685
  
686
/* rre.c */
687
688
extern Bool rfbSendRectEncodingRRE(rfbClientPtr cl, int x,int y,int w,int h);
689
690
691
/* corre.c */
692
693
extern Bool rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x,int y,int w,int h);
694
695
696
/* hextile.c */
697
698
extern Bool rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w,
699
				       int h);
700
701
702
/* zlib.c */
703
704
/* Minimum zlib rectangle size in bytes.  Anything smaller will
705
 * not compress well due to overhead.
706
 */
707
#define VNC_ENCODE_ZLIB_MIN_COMP_SIZE (17)
708
709
/* Set maximum zlib rectangle size in pixels.  Always allow at least
710
 * two scan lines.
711
 */
712
#define ZLIB_MAX_RECT_SIZE (128*256)
713
#define ZLIB_MAX_SIZE(min) ((( min * 2 ) > ZLIB_MAX_RECT_SIZE ) ? \
714
			    ( min * 2 ) : ZLIB_MAX_RECT_SIZE )
715
716
extern Bool rfbSendRectEncodingZlib(rfbClientPtr cl, int x, int y, int w,
717
				    int h);
718
719
720
/* tight.c */
721
722
#define TIGHT_DEFAULT_COMPRESSION  6
723
724
extern Bool rfbTightDisableGradient;
725
726
extern int rfbNumCodedRectsTight(rfbClientPtr cl, int x,int y,int w,int h);
727
extern Bool rfbSendRectEncodingTight(rfbClientPtr cl, int x,int y,int w,int h);
728
729
730
/* cursor.c */
731
732
extern Bool rfbSendCursorShape(rfbClientPtr cl, ScreenPtr pScreen);
733
extern Bool rfbSendCursorPos(rfbClientPtr cl, ScreenPtr pScreen);
734
735
736
/* stats.c */
737
738
extern void rfbResetStats(rfbClientPtr cl);
739
extern void rfbPrintStats(rfbClientPtr cl);
740
741
742
/* dpms.c */
743
744
extern Bool DPMSSupported(void);
745
extern int DPSMGet(int *level);
746
extern void DPMSSet(int level);
747
748
749
#endif /* RFB_H_INCLUDED */
(-)xorg-server-1.4.orig/hw/vnc/rfbkeyb.c (+405 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2002 Alan Hourihane.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this software; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 *
19
 *  Author: Alan Hourihane <alanh@fairlite.demon.co.uk>
20
 */
21
22
#ifdef HAVE_DIX_CONFIG_H
23
#include <dix-config.h>
24
#endif
25
26
#if XFREE86VNC
27
#ifndef XFree86LOADER
28
#include <unistd.h>
29
#include <errno.h>
30
#endif
31
32
#include <misc.h>
33
#include <xf86.h>
34
#if !defined(DGUX)
35
#include <xisb.h>
36
#endif
37
#include <xf86Xinput.h>
38
#include <exevents.h>		/* Needed for InitValuator/Proximity stuff */
39
#include <mipointer.h>
40
41
#ifdef XFree86LOADER
42
#include <xf86Module.h>
43
#endif
44
#else
45
#include <dix.h>
46
#include <mipointer.h>
47
#endif
48
#include "rfb.h"
49
50
51
extern void rfbSendBell(void);
52
extern DeviceIntPtr kbdDevice;
53
54
static const char *DEFAULTS[] = {
55
    NULL
56
};
57
58
#include <X11/keysym.h>
59
#include "keyboard.h"
60
61
#ifdef XKB
62
#include <X11/extensions/XKB.h>
63
#include <X11/extensions/XKBstr.h>
64
#include <X11/extensions/XKBsrv.h>
65
66
#if XFREE86VNC
67
    /* 
68
     * would like to use an XkbComponentNamesRec here but can't without
69
     * pulling in a bunch of header files. :-(
70
     */
71
static    char *		xkbkeymap;
72
static    char *		xkbkeycodes;
73
static    char *		xkbtypes;
74
static    char *		xkbcompat;
75
static    char *		xkbsymbols;
76
static    char *		xkbgeometry;
77
static    Bool		xkbcomponents_specified;
78
static    char *		xkbrules;
79
static    char *		xkbmodel;
80
static    char *		xkblayout;
81
static    char *		xkbvariant;
82
static    char *		xkboptions;
83
#endif
84
#endif
85
86
void
87
KbdDeviceInit(DeviceIntPtr pDevice, KeySymsPtr pKeySyms, CARD8 *pModMap)
88
{
89
    int i;
90
91
    for (i = 0; i < MAP_LENGTH; i++)
92
	pModMap[i] = NoSymbol;
93
94
    pModMap[CONTROL_L_KEY_CODE] = ControlMask;
95
    pModMap[CONTROL_R_KEY_CODE] = ControlMask;
96
    pModMap[SHIFT_L_KEY_CODE] = ShiftMask;
97
    pModMap[SHIFT_R_KEY_CODE] = ShiftMask;
98
    pModMap[META_L_KEY_CODE] = Mod1Mask;
99
    pModMap[META_R_KEY_CODE] = Mod1Mask;
100
    pModMap[ALT_L_KEY_CODE] = Mod1Mask;
101
    pModMap[ALT_R_KEY_CODE] = Mod1Mask;
102
103
    pKeySyms->minKeyCode = MIN_KEY_CODE;
104
    pKeySyms->maxKeyCode = MAX_KEY_CODE;
105
    pKeySyms->mapWidth = GLYPHS_PER_KEY;
106
107
    pKeySyms->map = (KeySym *)xalloc(sizeof(KeySym)
108
				     * MAP_LENGTH * GLYPHS_PER_KEY);
109
110
    if (!pKeySyms->map) {
111
	ErrorF("xalloc failed\n");
112
	exit(1);
113
    }
114
115
    for (i = 0; i < MAP_LENGTH * GLYPHS_PER_KEY; i++)
116
	pKeySyms->map[i] = NoSymbol;
117
118
    for (i = 0; i < N_PREDEFINED_KEYS * GLYPHS_PER_KEY; i++) {
119
	pKeySyms->map[i] = map[i];
120
    }
121
}
122
123
void
124
KbdDeviceOn(void)
125
{
126
}
127
128
129
void
130
KbdDeviceOff(void)
131
{
132
}
133
134
#if XFREE86VNC
135
static int
136
xf86rfbKeybControlProc(DeviceIntPtr device, int onoff)
137
{
138
    KeySymsRec		keySyms;
139
    CARD8 		modMap[MAP_LENGTH];
140
    DevicePtr pDev = (DevicePtr)device;
141
142
    switch (onoff)
143
    {
144
    case DEVICE_INIT: 
145
        vncSetKeyboardDevice(device);
146
	KbdDeviceInit(device, &keySyms, modMap);
147
#ifdef XKB
148
	if (noXkbExtension) {
149
#endif
150
	    InitKeyboardDeviceStruct(pDev, &keySyms, modMap,
151
				 (BellProcPtr)rfbSendBell,
152
				 (KbdCtrlProcPtr)NoopDDA);
153
#ifdef XKB
154
	} else {
155
 	    XkbComponentNamesRec names;
156
	    if (xkbkeymap) {
157
	    	names.keymap = xkbkeymap;
158
	    	names.keycodes = NULL;
159
	    	names.types = NULL;
160
	    	names.compat = NULL;
161
	    	names.symbols = NULL;
162
	    	names.geometry = NULL;
163
	    } else {
164
	    	names.keymap = NULL;
165
	    	names.keycodes = xkbkeycodes;
166
	    	names.types = xkbtypes;
167
	    	names.compat = xkbcompat;
168
	    	names.symbols = xkbsymbols;
169
	    	names.geometry = xkbgeometry;
170
	    }
171
	if ((xkbkeymap || xkbcomponents_specified)
172
	   && (xkbmodel == NULL || xkblayout == NULL)) {
173
		xkbrules = NULL;
174
	}
175
#if 0
176
	XkbSetRulesDflts(xkbrules, xkbmodel,
177
			 xkblayout, xkbvariant,
178
			 xkboptions);
179
#endif
180
	XkbInitKeyboardDeviceStruct(device, 
181
				    &names,
182
				    &keySyms, 
183
				    modMap, 
184
				    (BellProcPtr)rfbSendBell,
185
				    (KbdCtrlProcPtr)NoopDDA);
186
    }
187
#endif
188
	break;
189
    case DEVICE_ON: 
190
	pDev->on = TRUE;
191
	KbdDeviceOn();
192
	break;
193
    case DEVICE_OFF: 
194
	pDev->on = FALSE;
195
	KbdDeviceOff();
196
	break;
197
    case DEVICE_CLOSE:
198
        vncSetKeyboardDevice(NULL);
199
	if (pDev->on)
200
	    KbdDeviceOff();
201
	break;
202
    }
203
    return Success;
204
}
205
206
static void
207
xf86rfbKeybUninit(InputDriverPtr	drv,
208
	       InputInfoPtr	pInfo,
209
	       int		flags)
210
{
211
    xf86rfbKeybControlProc(pInfo->dev, DEVICE_OFF);
212
}
213
214
static InputInfoPtr
215
xf86rfbKeybInit(InputDriverPtr	drv,
216
	     IDevPtr		dev,
217
	     int		flags)
218
{
219
    InputInfoPtr pInfo;
220
    char *s;
221
    Bool from;
222
223
    if (!(pInfo = xf86AllocateInput(drv, 0)))
224
	return NULL;
225
226
    /* Initialise the InputInfoRec. */
227
    pInfo->name = dev->identifier;
228
    pInfo->type_name = "rfbKeyb";
229
    pInfo->flags = XI86_KEYBOARD_CAPABLE;
230
    pInfo->device_control = xf86rfbKeybControlProc;
231
    pInfo->read_input = NULL;
232
#if 0
233
    pInfo->motion_history_proc = NULL;
234
#endif
235
    pInfo->history_size = 0;
236
    pInfo->control_proc = NULL;
237
    pInfo->close_proc = NULL;
238
    pInfo->switch_mode = NULL;
239
    pInfo->conversion_proc = NULL;
240
    pInfo->reverse_conversion_proc = NULL;
241
    pInfo->fd = -1;
242
    pInfo->dev = NULL;
243
    pInfo->private_flags = 0;
244
    pInfo->always_core_feedback = 0;
245
    pInfo->conf_idev = dev;
246
247
    /* Collect the options, and process the common options. */
248
    xf86CollectInputOptions(pInfo, DEFAULTS, NULL);
249
    xf86ProcessCommonOptions(pInfo, pInfo->options);
250
    
251
    /* Mark the device configured */
252
    pInfo->flags |= XI86_CONFIGURED;
253
254
#ifdef XKB
255
  from = X_DEFAULT;
256
  if (noXkbExtension)
257
    from = X_CMDLINE;
258
  else if (xf86FindOption(dev->commonOptions, "XkbDisable")) {
259
    noXkbExtension =
260
	xf86SetBoolOption(dev->commonOptions, "XkbDisable", FALSE);
261
    from = X_CONFIG;
262
  }
263
  if (noXkbExtension)
264
    xf86Msg(from, "XKB: disabled\n");
265
266
#define NULL_IF_EMPTY(s) (s[0] ? s : (xfree(s), (char *)NULL))
267
268
  if (!noXkbExtension) {
269
    if ((s = xf86SetStrOption(dev->commonOptions, "XkbKeymap", NULL))) {
270
      xkbkeymap = NULL_IF_EMPTY(s);
271
      xf86Msg(X_CONFIG, "XKB: keymap: \"%s\" "
272
		"(overrides other XKB settings)\n", xkbkeymap);
273
    } else {
274
      if ((s = xf86SetStrOption(dev->commonOptions, "XkbCompat", NULL))) {
275
	xkbcompat = NULL_IF_EMPTY(s);
276
	xkbcomponents_specified = TRUE;
277
	xf86Msg(X_CONFIG, "XKB: compat: \"%s\"\n", s);
278
      }
279
280
      if ((s = xf86SetStrOption(dev->commonOptions, "XkbTypes", NULL))) {
281
	xkbtypes = NULL_IF_EMPTY(s);
282
	xkbcomponents_specified = TRUE;
283
	xf86Msg(X_CONFIG, "XKB: types: \"%s\"\n", s);
284
      }
285
286
      if ((s = xf86SetStrOption(dev->commonOptions, "XkbKeycodes", NULL))) {
287
	xkbkeycodes = NULL_IF_EMPTY(s);
288
	xkbcomponents_specified = TRUE;
289
	xf86Msg(X_CONFIG, "XKB: keycodes: \"%s\"\n", s);
290
      }
291
292
      if ((s = xf86SetStrOption(dev->commonOptions, "XkbGeometry", NULL))) {
293
	xkbgeometry = NULL_IF_EMPTY(s);
294
	xkbcomponents_specified = TRUE;
295
	xf86Msg(X_CONFIG, "XKB: geometry: \"%s\"\n", s);
296
      }
297
298
      if ((s = xf86SetStrOption(dev->commonOptions, "XkbSymbols", NULL))) {
299
	xkbsymbols = NULL_IF_EMPTY(s);
300
	xkbcomponents_specified = TRUE;
301
	xf86Msg(X_CONFIG, "XKB: symbols: \"%s\"\n", s);
302
      }
303
304
      if ((s = xf86SetStrOption(dev->commonOptions, "XkbRules", NULL))) {
305
	xkbrules = NULL_IF_EMPTY(s);
306
	xkbcomponents_specified = TRUE;
307
	xf86Msg(X_CONFIG, "XKB: rules: \"%s\"\n", s);
308
      }
309
310
      if ((s = xf86SetStrOption(dev->commonOptions, "XkbModel", NULL))) {
311
	xkbmodel = NULL_IF_EMPTY(s);
312
	xkbcomponents_specified = TRUE;
313
	xf86Msg(X_CONFIG, "XKB: model: \"%s\"\n", s);
314
      }
315
316
      if ((s = xf86SetStrOption(dev->commonOptions, "XkbLayout", NULL))) {
317
	xkblayout = NULL_IF_EMPTY(s);
318
	xkbcomponents_specified = TRUE;
319
	xf86Msg(X_CONFIG, "XKB: layout: \"%s\"\n", s);
320
      }
321
322
      if ((s = xf86SetStrOption(dev->commonOptions, "XkbVariant", NULL))) {
323
	xkbvariant = NULL_IF_EMPTY(s);
324
	xkbcomponents_specified = TRUE;
325
	xf86Msg(X_CONFIG, "XKB: variant: \"%s\"\n", s);
326
      }
327
328
      if ((s = xf86SetStrOption(dev->commonOptions, "XkbOptions", NULL))) {
329
	xkboptions = NULL_IF_EMPTY(s);
330
	xkbcomponents_specified = TRUE;
331
	xf86Msg(X_CONFIG, "XKB: options: \"%s\"\n", s);
332
      }
333
    }
334
  }
335
#undef NULL_IF_EMPTY
336
#endif
337
338
    /* Return the configured device */
339
    return (pInfo);
340
}
341
342
#ifdef XFree86LOADER
343
static
344
#endif
345
InputDriverRec RFBKEYB = {
346
    1,				/* driver version */
347
    "rfbkeyb",			/* driver name */
348
    NULL,			/* identify */
349
    xf86rfbKeybInit,		/* pre-init */
350
    xf86rfbKeybUninit,		/* un-init */
351
    NULL,			/* module */
352
    0				/* ref count */
353
};
354
355
/*
356
 ***************************************************************************
357
 *
358
 * Dynamic loading functions
359
 *
360
 ***************************************************************************
361
 */
362
#ifdef XFree86LOADER
363
static void
364
xf86rfbKeybUnplug(pointer	p)
365
{
366
}
367
368
static pointer
369
xf86rfbKeybPlug(pointer	module,
370
	    pointer	options,
371
	    int		*errmaj,
372
	    int		*errmin)
373
{
374
    xf86AddInputDriver(&RFBKEYB, module, 0);
375
376
    return module;
377
}
378
379
void
380
vncInitKeyb(void)
381
{
382
    xf86AddInputDriver(&RFBKEYB, NULL, 0);
383
}
384
385
static XF86ModuleVersionInfo xf86rfbKeybVersionRec =
386
{
387
    "rfbkeyb",
388
    "xf4vnc Project, see http://xf4vnc.sf.net",
389
    MODINFOSTRING1,
390
    MODINFOSTRING2,
391
    XF86_VERSION_CURRENT,
392
    1, 0, 0,
393
    ABI_CLASS_XINPUT,
394
    ABI_XINPUT_VERSION,
395
    MOD_CLASS_XINPUT,
396
    {0, 0, 0, 0}		/* signature, to be patched into the file by */
397
				/* a tool */
398
};
399
400
XF86ModuleData rfbkeybModuleData = {&xf86rfbKeybVersionRec,
401
				  xf86rfbKeybPlug,
402
				  xf86rfbKeybUnplug};
403
404
#endif /* XFree86LOADER */
405
#endif
(-)xorg-server-1.4.orig/hw/vnc/rfbmouse.c (+260 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2002 Alan Hourihane.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this software; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 *
19
 *  Author: Alan Hourihane <alanh@fairlite.demon.co.uk>
20
 */
21
#ifdef HAVE_DIX_CONFIG_H
22
#include <dix-config.h>
23
#endif
24
25
26
#include <X11/keysym.h>
27
#if XFREE86VNC
28
#ifndef XFree86LOADER
29
#include <unistd.h>
30
#include <errno.h>
31
#endif
32
33
#include <misc.h>
34
#include <xf86.h>
35
#if !defined(DGUX)
36
#include <xisb.h>
37
#endif
38
#include <xf86Xinput.h>
39
#include <exevents.h>		/* Needed for InitValuator/Proximity stuff */
40
#include <mipointer.h>
41
42
#ifdef XFree86LOADER
43
#include <xf86Module.h>
44
#endif
45
46
static const char *DEFAULTS[] = {
47
    NULL
48
};
49
#else
50
#include <dix.h>
51
#include <mipointer.h>
52
#endif
53
#include "rfb.h"
54
55
56
unsigned char ptrAcceleration = 50;
57
58
void
59
PtrDeviceOn(DeviceIntPtr pDev)
60
{
61
#if 0
62
    ptrAcceleration = (unsigned char)pDev->ptrfeed->ctrl.num;
63
#endif
64
}
65
66
void
67
PtrDeviceInit(void)
68
{
69
}
70
71
void
72
PtrDeviceOff(void)
73
{
74
}
75
76
77
void
78
PtrDeviceControl(DeviceIntPtr dev, PtrCtrl *ctrl)
79
{
80
#if 0
81
    ptrAcceleration = (char)ctrl->num;
82
83
    if (udpSockConnected) {
84
	if (write(udpSock, &ptrAcceleration, 1) <= 0) {
85
	    ErrorF("PtrDeviceControl: UDP input: write");
86
	    rfbDisconnectUDPSock();
87
	}
88
    }
89
#endif
90
}
91
92
#if XFREE86VNC
93
static int
94
xf86rfbMouseControlProc(DeviceIntPtr device, int onoff)
95
{
96
    BYTE map[6];
97
    DevicePtr pDev = (DevicePtr)device;
98
    void *func1;
99
    int (*func2)(void);
100
101
    if (LoaderSymbol("GetMotionHistory"))
102
    	func1 = LoaderSymbol("GetMotionHistory");
103
    else
104
    	func1 = LoaderSymbol("miPointerGetMotionEvents");
105
106
    if (LoaderSymbol("GetMotionHistorySize"))
107
    	func2 = LoaderSymbol("GetMotionHistorySize");
108
    else
109
    	func2 = LoaderSymbol("miPointerGetMotionBufferSize");
110
111
112
    switch (onoff)
113
    {
114
    case DEVICE_INIT:
115
        vncSetPointerDevice(device);
116
	PtrDeviceInit();
117
	map[1] = 1;
118
	map[2] = 2;
119
	map[3] = 3;
120
	map[4] = 4;
121
	map[5] = 5;
122
	InitPointerDeviceStruct(pDev, map, 5, 
123
                                func1,
124
				PtrDeviceControl,
125
                                (*func2)(), 2);
126
	break;
127
128
    case DEVICE_ON:
129
	pDev->on = TRUE;
130
	PtrDeviceOn(device);
131
        break;
132
133
    case DEVICE_OFF:
134
	pDev->on = FALSE;
135
	PtrDeviceOff();
136
	break;
137
138
    case DEVICE_CLOSE:
139
        vncSetPointerDevice(NULL);
140
	if (pDev->on)
141
	    PtrDeviceOff();
142
	break;
143
    }
144
    return Success;
145
}
146
147
static void
148
xf86rfbMouseUninit(InputDriverPtr	drv,
149
	       InputInfoPtr	pInfo,
150
	       int		flags)
151
{
152
    xf86rfbMouseControlProc(pInfo->dev, DEVICE_OFF);
153
}
154
155
static InputInfoPtr
156
xf86rfbMouseInit(InputDriverPtr	drv,
157
	     IDevPtr		dev,
158
	     int		flags)
159
{
160
    InputInfoPtr pInfo;
161
162
    if (!(pInfo = xf86AllocateInput(drv, 0)))
163
	return NULL;
164
165
    /* Initialise the InputInfoRec. */
166
    pInfo->name = dev->identifier;
167
    pInfo->type_name = "rfbMouse";
168
    pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
169
    pInfo->device_control = xf86rfbMouseControlProc;
170
    pInfo->read_input = NULL;
171
#if 0
172
    pInfo->motion_history_proc = xf86GetMotionEvents;
173
#endif
174
    pInfo->history_size = 0;
175
    pInfo->control_proc = NULL;
176
    pInfo->close_proc = NULL;
177
    pInfo->switch_mode = NULL;
178
    pInfo->conversion_proc = NULL;
179
    pInfo->reverse_conversion_proc = NULL;
180
    pInfo->fd = -1;
181
    pInfo->dev = NULL;
182
    pInfo->private_flags = 0;
183
    pInfo->always_core_feedback = 0;
184
    pInfo->conf_idev = dev;
185
186
    /* Collect the options, and process the common options. */
187
    xf86CollectInputOptions(pInfo, DEFAULTS, NULL);
188
    xf86ProcessCommonOptions(pInfo, pInfo->options);
189
    
190
    /* Mark the device configured */
191
    pInfo->flags |= XI86_CONFIGURED;
192
193
    /* Return the configured device */
194
    return (pInfo);
195
}
196
197
#ifdef XFree86LOADER
198
static
199
#endif
200
InputDriverRec RFBMOUSE = {
201
    1,				/* driver version */
202
    "rfbmouse",			/* driver name */
203
    NULL,			/* identify */
204
    xf86rfbMouseInit,		/* pre-init */
205
    xf86rfbMouseUninit,		/* un-init */
206
    NULL,			/* module */
207
    0				/* ref count */
208
};
209
210
/*
211
 ***************************************************************************
212
 *
213
 * Dynamic loading functions
214
 *
215
 ***************************************************************************
216
 */
217
#ifdef XFree86LOADER
218
static void
219
xf86rfbMouseUnplug(pointer	p)
220
{
221
}
222
223
static pointer
224
xf86rfbMousePlug(pointer	module,
225
	    pointer	options,
226
	    int		*errmaj,
227
	    int		*errmin)
228
{
229
    xf86AddInputDriver(&RFBMOUSE, module, 0);
230
231
    return module;
232
}
233
234
void
235
vncInitMouse(void)
236
{
237
    xf86AddInputDriver(&RFBMOUSE, NULL, 0);
238
}
239
240
static XF86ModuleVersionInfo xf86rfbMouseVersionRec =
241
{
242
    "rfbmouse",
243
    "xf4vnc Project, see http://xf4vnc.sf.net",
244
    MODINFOSTRING1,
245
    MODINFOSTRING2,
246
    XF86_VERSION_CURRENT,
247
    1, 0, 0,
248
    ABI_CLASS_XINPUT,
249
    ABI_XINPUT_VERSION,
250
    MOD_CLASS_XINPUT,
251
    {0, 0, 0, 0}		/* signature, to be patched into the file by */
252
				/* a tool */
253
};
254
255
XF86ModuleData rfbmouseModuleData = {&xf86rfbMouseVersionRec,
256
				  xf86rfbMousePlug,
257
				  xf86rfbMouseUnplug};
258
259
#endif /* XFree86LOADER */
260
#endif
(-)xorg-server-1.4.orig/hw/vnc/rfbproto.h (+1362 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2000-2004 Constantin Kaplinsky. All Rights Reserved.
3
 *  Copyright (C) 2000 Tridia Corporation. All Rights Reserved.
4
 *  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
5
 *
6
 *  This is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This software is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this software; if not, write to the Free Software
18
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
19
 *  USA.
20
 */
21
22
/*
23
 * rfbproto.h - header file for the RFB protocol, versions 3.3, 3.7 and 3.7t
24
 * (protocol 3.7t is effectively 3.7 with TightVNC extensions enabled)
25
 *
26
 * Uses types CARD<n> for an n-bit unsigned integer, INT<n> for an n-bit signed
27
 * integer (for n = 8, 16 and 32).
28
 *
29
 * All multiple byte integers are in big endian (network) order (most
30
 * significant byte first).  Unless noted otherwise there is no special
31
 * alignment of protocol structures.
32
 *
33
 *
34
 * Once the initial handshaking is done, all messages start with a type byte,
35
 * (usually) followed by message-specific data.  The order of definitions in
36
 * this file is as follows:
37
 *
38
 *  (1) Structures used in several types of message.
39
 *  (2) Structures used in the initial handshaking.
40
 *  (3) Message types.
41
 *  (4) Encoding types.
42
 *  (5) For each message type, the form of the data following the type byte.
43
 *      Sometimes this is defined by a single structure but the more complex
44
 *      messages have to be explained by comments.
45
 */
46
47
48
/*****************************************************************************
49
 *
50
 * Structures used in several messages
51
 *
52
 *****************************************************************************/
53
54
/*-----------------------------------------------------------------------------
55
 * Structure used to specify a rectangle.  This structure is a multiple of 4
56
 * bytes so that it can be interspersed with 32-bit pixel data without
57
 * affecting alignment.
58
 */
59
60
typedef struct _rfbRectangle {
61
    CARD16 x;
62
    CARD16 y;
63
    CARD16 w;
64
    CARD16 h;
65
} rfbRectangle;
66
67
#define sz_rfbRectangle 8
68
69
70
/*-----------------------------------------------------------------------------
71
 * Structure used to specify pixel format.
72
 */
73
74
typedef struct _rfbPixelFormat {
75
76
    CARD8 bitsPerPixel;		/* 8,16,32 only */
77
78
    CARD8 depth;		/* 8 to 32 */
79
80
    CARD8 bigEndian;		/* True if multi-byte pixels are interpreted
81
				   as big endian, or if single-bit-per-pixel
82
				   has most significant bit of the byte
83
				   corresponding to first (leftmost) pixel. Of
84
				   course this is meaningless for 8 bits/pix */
85
86
    CARD8 trueColour;		/* If false then we need a "colour map" to
87
				   convert pixels to RGB.  If true, xxxMax and
88
				   xxxShift specify bits used for red, green
89
				   and blue */
90
91
    /* the following fields are only meaningful if trueColour is true */
92
93
    CARD16 redMax;		/* maximum red value (= 2^n - 1 where n is the
94
				   number of bits used for red). Note this
95
				   value is always in big endian order. */
96
97
    CARD16 greenMax;		/* similar for green */
98
99
    CARD16 blueMax;		/* and blue */
100
101
    CARD8 redShift;		/* number of shifts needed to get the red
102
				   value in a pixel to the least significant
103
				   bit. To find the red value from a given
104
				   pixel, do the following:
105
				   1) Swap pixel value according to bigEndian
106
				      (e.g. if bigEndian is false and host byte
107
				      order is big endian, then swap).
108
				   2) Shift right by redShift.
109
				   3) AND with redMax (in host byte order).
110
				   4) You now have the red value between 0 and
111
				      redMax. */
112
113
    CARD8 greenShift;		/* similar for green */
114
115
    CARD8 blueShift;		/* and blue */
116
117
    CARD8 pad1;
118
    CARD16 pad2;
119
120
} rfbPixelFormat;
121
122
#define sz_rfbPixelFormat 16
123
124
125
/*-----------------------------------------------------------------------------
126
 * Structure used to describe protocol options such as tunneling methods,
127
 * authentication schemes and message types (protocol version 3.7t).
128
 */
129
130
typedef struct _rfbCapabilityInfo {
131
132
    CARD32 code;		/* numeric identifier */
133
    CARD8 vendorSignature[4];	/* vendor identification */
134
    CARD8 nameSignature[8];	/* abbreviated option name */
135
136
} rfbCapabilityInfo;
137
138
#define sz_rfbCapabilityInfoVendor 4
139
#define sz_rfbCapabilityInfoName 8
140
#define sz_rfbCapabilityInfo 16
141
142
/*
143
 * Vendors known by TightVNC: standard VNC/RealVNC, TridiaVNC, and TightVNC.
144
 */
145
146
#define rfbStandardVendor "STDV"
147
#define rfbTridiaVncVendor "TRDV"
148
#define rfbTightVncVendor "TGHT"
149
#define rfbTungstenGraphicsVendor "TGIV"
150
151
152
/*****************************************************************************
153
 *
154
 * Initial handshaking messages
155
 *
156
 *****************************************************************************/
157
158
/*-----------------------------------------------------------------------------
159
 * Protocol Version
160
 *
161
 * The server always sends 12 bytes to start which identifies the latest RFB
162
 * protocol version number which it supports.  These bytes are interpreted
163
 * as a string of 12 ASCII characters in the format "RFB xxx.yyy\n" where
164
 * xxx and yyy are the major and minor version numbers (for version 3.7
165
 * this is "RFB 003.007\n").
166
 *
167
 * The client then replies with a similar 12-byte message giving the version
168
 * number of the protocol which should actually be used (which may be different
169
 * to that quoted by the server).
170
 *
171
 * It is intended that both clients and servers may provide some level of
172
 * backwards compatibility by this mechanism.  Servers in particular should
173
 * attempt to provide backwards compatibility, and even forwards compatibility
174
 * to some extent.  For example if a client demands version 3.1 of the
175
 * protocol, a 3.0 server can probably assume that by ignoring requests for
176
 * encoding types it doesn't understand, everything will still work OK.  This
177
 * will probably not be the case for changes in the major version number.
178
 *
179
 * The format string below can be used in sprintf or sscanf to generate or
180
 * decode the version string respectively.
181
 */
182
183
#define rfbProtocolVersionFormat "RFB %03d.%03d\n"
184
#define rfbProtocolMajorVersion 3
185
#define rfbProtocolMinorVersion 7
186
#define rfbProtocolFallbackMinorVersion 3
187
188
typedef char rfbProtocolVersionMsg[13];	/* allow extra byte for null */
189
190
#define sz_rfbProtocolVersionMsg 12
191
192
193
/*
194
 * Negotiation of the security type (protocol version 3.7)
195
 *
196
 * Once the protocol version has been decided, the server either sends a list
197
 * of supported security types, or informs the client about an error (when the
198
 * number of security types is 0).  Security type rfbSecTypeTight is used to
199
 * enable TightVNC-specific protocol extensions.  The value rfbSecTypeVncAuth
200
 * stands for classic VNC authentication.
201
 *
202
 * The client selects a particular security type from the list provided by the
203
 * server.
204
 */
205
206
#define rfbSecTypeInvalid 0
207
#define rfbSecTypeNone 1
208
#define rfbSecTypeVncAuth 2
209
#define rfbSecTypeTight 16
210
211
212
/*-----------------------------------------------------------------------------
213
 * Negotiation of Tunneling Capabilities (protocol version 3.7t)
214
 *
215
 * If the chosen security type is rfbSecTypeTight, the server sends a list of
216
 * supported tunneling methods ("tunneling" refers to any additional layer of
217
 * data transformation, such as encryption or external compression.)
218
 *
219
 * nTunnelTypes specifies the number of following rfbCapabilityInfo structures
220
 * that list all supported tunneling methods in the order of preference.
221
 *
222
 * NOTE: If nTunnelTypes is 0, that tells the client that no tunneling can be
223
 * used, and the client should not send a response requesting a tunneling
224
 * method.
225
 */
226
227
typedef struct _rfbTunnelingCapsMsg {
228
    CARD32 nTunnelTypes;
229
    /* followed by nTunnelTypes * rfbCapabilityInfo structures */
230
} rfbTunnelingCapsMsg;
231
232
#define sz_rfbTunnelingCapsMsg 4
233
234
/*-----------------------------------------------------------------------------
235
 * Tunneling Method Request (protocol version 3.7t)
236
 *
237
 * If the list of tunneling capabilities sent by the server was not empty, the
238
 * client should reply with a 32-bit code specifying a particular tunneling
239
 * method.  The following code should be used for no tunneling.
240
 */
241
242
#define rfbNoTunneling 0
243
#define sig_rfbNoTunneling "NOTUNNEL"
244
245
246
/*-----------------------------------------------------------------------------
247
 * Negotiation of Authentication Capabilities (protocol version 3.7t)
248
 *
249
 * After setting up tunneling, the server sends a list of supported
250
 * authentication schemes.
251
 *
252
 * nAuthTypes specifies the number of following rfbCapabilityInfo structures
253
 * that list all supported authentication schemes in the order of preference.
254
 *
255
 * NOTE: If nAuthTypes is 0, that tells the client that no authentication is
256
 * necessary, and the client should not send a response requesting an
257
 * authentication scheme.
258
 */
259
260
typedef struct _rfbAuthenticationCapsMsg {
261
    CARD32 nAuthTypes;
262
    /* followed by nAuthTypes * rfbCapabilityInfo structures */
263
} rfbAuthenticationCapsMsg;
264
265
#define sz_rfbAuthenticationCapsMsg 4
266
267
/*-----------------------------------------------------------------------------
268
 * Authentication Scheme Request (protocol version 3.7t)
269
 *
270
 * If the list of authentication capabilities sent by the server was not empty,
271
 * the client should reply with a 32-bit code specifying a particular
272
 * authentication scheme.  The following codes are supported.
273
 */
274
275
#define rfbAuthNone 1
276
#define rfbAuthVNC 2
277
#define rfbAuthUnixLogin 129
278
#define rfbAuthExternal 130
279
280
#define sig_rfbAuthNone "NOAUTH__"
281
#define sig_rfbAuthVNC "VNCAUTH_"
282
#define sig_rfbAuthUnixLogin "ULGNAUTH"
283
#define sig_rfbAuthExternal "XTRNAUTH"
284
285
286
/*-----------------------------------------------------------------------------
287
 * Standard VNC Authentication (all protocol versions)
288
 *
289
 * Standard authentication result codes are defined below.
290
 */
291
292
#define rfbVncAuthOK 0
293
#define rfbVncAuthFailed 1
294
#define rfbVncAuthTooMany 2
295
296
297
/*-----------------------------------------------------------------------------
298
 * Client Initialisation Message
299
 *
300
 * Once the client and server are sure that they're happy to talk to one
301
 * another, the client sends an initialisation message.  At present this
302
 * message only consists of a boolean indicating whether the server should try
303
 * to share the desktop by leaving other clients connected, or give exclusive
304
 * access to this client by disconnecting all other clients.
305
 */
306
307
typedef struct _rfbClientInitMsg {
308
    CARD8 shared;
309
} rfbClientInitMsg;
310
311
#define sz_rfbClientInitMsg 1
312
313
314
/*-----------------------------------------------------------------------------
315
 * Server Initialisation Message
316
 *
317
 * After the client initialisation message, the server sends one of its own.
318
 * This tells the client the width and height of the server's framebuffer,
319
 * its pixel format and the name associated with the desktop.
320
 */
321
322
typedef struct _rfbServerInitMsg {
323
    CARD16 framebufferWidth;
324
    CARD16 framebufferHeight;
325
    rfbPixelFormat format;	/* the server's preferred pixel format */
326
    CARD32 nameLength;
327
    /* followed by char name[nameLength] */
328
} rfbServerInitMsg;
329
330
#define sz_rfbServerInitMsg (8 + sz_rfbPixelFormat)
331
332
333
/*-----------------------------------------------------------------------------
334
 * Server Interaction Capabilities Message (protocol version 3.7t)
335
 *
336
 * In the protocol version 3.7t, the server informs the client what message
337
 * types it supports in addition to ones defined in the protocol version 3.7.
338
 * Also, the server sends the list of all supported encodings (note that it's
339
 * not necessary to advertise the "raw" encoding sinse it MUST be supported in
340
 * RFB 3.x protocols).
341
 *
342
 * This data immediately follows the server initialisation message.
343
 */
344
345
typedef struct _rfbInteractionCapsMsg {
346
    CARD16 nServerMessageTypes;
347
    CARD16 nClientMessageTypes;
348
    CARD16 nEncodingTypes;
349
    CARD16 pad;			/* reserved, must be 0 */
350
    /* followed by nServerMessageTypes * rfbCapabilityInfo structures */
351
    /* followed by nClientMessageTypes * rfbCapabilityInfo structures */
352
} rfbInteractionCapsMsg;
353
354
#define sz_rfbInteractionCapsMsg 8
355
356
357
/*
358
 * Following the server initialisation message it's up to the client to send
359
 * whichever protocol messages it wants.  Typically it will send a
360
 * SetPixelFormat message and a SetEncodings message, followed by a
361
 * FramebufferUpdateRequest.  From then on the server will send
362
 * FramebufferUpdate messages in response to the client's
363
 * FramebufferUpdateRequest messages.  The client should send
364
 * FramebufferUpdateRequest messages with incremental set to true when it has
365
 * finished processing one FramebufferUpdate and is ready to process another.
366
 * With a fast client, the rate at which FramebufferUpdateRequests are sent
367
 * should be regulated to avoid hogging the network.
368
 */
369
370
371
372
/*****************************************************************************
373
 *
374
 * Message types
375
 *
376
 *****************************************************************************/
377
378
/* server -> client */
379
380
#define rfbFramebufferUpdate 0
381
#define rfbSetColourMapEntries 1
382
#define rfbBell 2
383
#define rfbServerCutText 3
384
/* Chromium extensions, use higher values */
385
#define rfbChromiumStart 50 
386
#define rfbChromiumMoveResizeWindow 51
387
#define rfbChromiumClipList 52
388
#define rfbChromiumWindowShow 53
389
#define rfbChromiumWindowDestroy 54
390
391
#define rfbFileListData 130
392
#define rfbFileDownloadData 131
393
#define rfbFileUploadCancel 132
394
#define rfbFileDownloadFailed 133
395
396
/* signatures for non-standard messages */
397
#define sig_rfbFileListData "FTS_LSDT"
398
#define sig_rfbFileDownloadData "FTS_DNDT"
399
#define sig_rfbFileUploadCancel "FTS_UPCN"
400
#define sig_rfbFileDownloadFailed "FTS_DNFL"
401
402
403
/* client -> server */
404
405
#define rfbSetPixelFormat 0
406
#define rfbFixColourMapEntries 1	/* not currently supported */
407
#define rfbSetEncodings 2
408
#define rfbFramebufferUpdateRequest 3
409
#define rfbKeyEvent 4
410
#define rfbPointerEvent 5
411
#define rfbClientCutText 6
412
/* Chromium extensions, use higher values */
413
#define rfbChromiumStop 50
414
#define rfbChromiumExpose 51
415
416
#define rfbFileListRequest 130
417
#define rfbFileDownloadRequest 131
418
#define rfbFileUploadRequest 132
419
#define rfbFileUploadData 133
420
#define rfbFileDownloadCancel 134
421
#define rfbFileUploadFailed 135
422
#define rfbFileCreateDirRequest 136
423
424
/* signatures for non-standard messages */
425
#define sig_rfbFileListRequest "FTC_LSRQ"
426
#define sig_rfbFileDownloadRequest "FTC_DNRQ"
427
#define sig_rfbFileUploadRequest "FTC_UPRQ"
428
#define sig_rfbFileUploadData "FTC_UPDT"
429
#define sig_rfbFileDownloadCancel "FTC_DNCN"
430
#define sig_rfbFileUploadFailed "FTC_UPFL"
431
#define sig_rfbFileCreateDirRequest "FTC_FCDR"
432
433
/*****************************************************************************
434
 *
435
 * Encoding types
436
 *
437
 *****************************************************************************/
438
439
#define rfbEncodingRaw       0
440
#define rfbEncodingCopyRect  1
441
#define rfbEncodingRRE       2
442
#define rfbEncodingCoRRE     4
443
#define rfbEncodingHextile   5
444
#define rfbEncodingZlib      6
445
#define rfbEncodingTight     7
446
#define rfbEncodingZlibHex   8
447
448
/* signatures for basic encoding types */
449
#define sig_rfbEncodingRaw       "RAW_____"
450
#define sig_rfbEncodingCopyRect  "COPYRECT"
451
#define sig_rfbEncodingRRE       "RRE_____"
452
#define sig_rfbEncodingCoRRE     "CORRE___"
453
#define sig_rfbEncodingHextile   "HEXTILE_"
454
#define sig_rfbEncodingZlib      "ZLIB____"
455
#define sig_rfbEncodingTight     "TIGHT___"
456
#define sig_rfbEncodingZlibHex   "ZLIBHEX_"
457
#define sig_rfbEncodingChromium  "CHROMIUM"
458
459
/*
460
 * Special encoding numbers:
461
 *   0xFFFFFF00 .. 0xFFFFFF0F -- encoding-specific compression levels;
462
 *   0xFFFFFF10 .. 0xFFFFFF1F -- mouse cursor shape data;
463
 *   0xFFFFFF20 .. 0xFFFFFF2F -- various protocol extensions;
464
 *   0xFFFFFF30 .. 0xFFFFFFDF -- not allocated yet;
465
 *   0xFFFFFFE0 .. 0xFFFFFFEF -- quality level for JPEG compressor;
466
 *   0xFFFFFFF0 .. 0xFFFFFFFF -- not allocated yet.
467
 */
468
469
#define rfbEncodingCompressLevel0  0xFFFFFF00
470
#define rfbEncodingCompressLevel1  0xFFFFFF01
471
#define rfbEncodingCompressLevel2  0xFFFFFF02
472
#define rfbEncodingCompressLevel3  0xFFFFFF03
473
#define rfbEncodingCompressLevel4  0xFFFFFF04
474
#define rfbEncodingCompressLevel5  0xFFFFFF05
475
#define rfbEncodingCompressLevel6  0xFFFFFF06
476
#define rfbEncodingCompressLevel7  0xFFFFFF07
477
#define rfbEncodingCompressLevel8  0xFFFFFF08
478
#define rfbEncodingCompressLevel9  0xFFFFFF09
479
480
#define rfbEncodingXCursor         0xFFFFFF10
481
#define rfbEncodingRichCursor      0xFFFFFF11
482
#define rfbEncodingPointerPos      0xFFFFFF18
483
484
#define rfbEncodingLastRect        0xFFFFFF20
485
#define rfbEncodingNewFBSize       0xFFFFFF21
486
#define rfbEncodingChromium	   0xFFFFFF2F
487
#define rfbEncodingChromium2       0xFFFFFF30
488
489
#define rfbEncodingQualityLevel0   0xFFFFFFE0
490
#define rfbEncodingQualityLevel1   0xFFFFFFE1
491
#define rfbEncodingQualityLevel2   0xFFFFFFE2
492
#define rfbEncodingQualityLevel3   0xFFFFFFE3
493
#define rfbEncodingQualityLevel4   0xFFFFFFE4
494
#define rfbEncodingQualityLevel5   0xFFFFFFE5
495
#define rfbEncodingQualityLevel6   0xFFFFFFE6
496
#define rfbEncodingQualityLevel7   0xFFFFFFE7
497
#define rfbEncodingQualityLevel8   0xFFFFFFE8
498
#define rfbEncodingQualityLevel9   0xFFFFFFE9
499
500
/* signatures for "fake" encoding types */
501
#define sig_rfbEncodingCompressLevel0  "COMPRLVL"
502
#define sig_rfbEncodingXCursor         "X11CURSR"
503
#define sig_rfbEncodingRichCursor      "RCHCURSR"
504
#define sig_rfbEncodingPointerPos      "POINTPOS"
505
#define sig_rfbEncodingLastRect        "LASTRECT"
506
#define sig_rfbEncodingNewFBSize       "NEWFBSIZ"
507
#define sig_rfbEncodingQualityLevel0   "JPEGQLVL"
508
509
510
/*****************************************************************************
511
 *
512
 * Server -> client message definitions
513
 *
514
 *****************************************************************************/
515
516
517
/*-----------------------------------------------------------------------------
518
 * FramebufferUpdate - a block of rectangles to be copied to the framebuffer.
519
 *
520
 * This message consists of a header giving the number of rectangles of pixel
521
 * data followed by the rectangles themselves.  The header is padded so that
522
 * together with the type byte it is an exact multiple of 4 bytes (to help
523
 * with alignment of 32-bit pixels):
524
 */
525
526
typedef struct _rfbFramebufferUpdateMsg {
527
    CARD8 type;			/* always rfbFramebufferUpdate */
528
    CARD8 pad;
529
    CARD16 nRects;
530
    /* followed by nRects rectangles */
531
} rfbFramebufferUpdateMsg;
532
533
#define sz_rfbFramebufferUpdateMsg 4
534
535
/*
536
 * Each rectangle of pixel data consists of a header describing the position
537
 * and size of the rectangle and a type word describing the encoding of the
538
 * pixel data, followed finally by the pixel data.  Note that if the client has
539
 * not sent a SetEncodings message then it will only receive raw pixel data.
540
 * Also note again that this structure is a multiple of 4 bytes.
541
 */
542
543
typedef struct _rfbFramebufferUpdateRectHeader {
544
    rfbRectangle r;
545
    CARD32 encoding;		/* one of the encoding types rfbEncoding... */
546
} rfbFramebufferUpdateRectHeader;
547
548
#define sz_rfbFramebufferUpdateRectHeader (sz_rfbRectangle + 4)
549
550
551
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
552
 * Raw Encoding.  Pixels are sent in top-to-bottom scanline order,
553
 * left-to-right within a scanline with no padding in between.
554
 */
555
556
557
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
558
 * CopyRect Encoding.  The pixels are specified simply by the x and y position
559
 * of the source rectangle.
560
 */
561
562
typedef struct _rfbCopyRect {
563
    CARD16 srcX;
564
    CARD16 srcY;
565
} rfbCopyRect;
566
567
#define sz_rfbCopyRect 4
568
569
570
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
571
 * RRE - Rise-and-Run-length Encoding.  We have an rfbRREHeader structure
572
 * giving the number of subrectangles following.  Finally the data follows in
573
 * the form [<bgpixel><subrect><subrect>...] where each <subrect> is
574
 * [<pixel><rfbRectangle>].
575
 */
576
577
typedef struct _rfbRREHeader {
578
    CARD32 nSubrects;
579
} rfbRREHeader;
580
581
#define sz_rfbRREHeader 4
582
583
584
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
585
 * CoRRE - Compact RRE Encoding.  We have an rfbRREHeader structure giving
586
 * the number of subrectangles following.  Finally the data follows in the form
587
 * [<bgpixel><subrect><subrect>...] where each <subrect> is
588
 * [<pixel><rfbCoRRERectangle>].  This means that
589
 * the whole rectangle must be at most 255x255 pixels.
590
 */
591
592
typedef struct _rfbCoRRERectangle {
593
    CARD8 x;
594
    CARD8 y;
595
    CARD8 w;
596
    CARD8 h;
597
} rfbCoRRERectangle;
598
599
#define sz_rfbCoRRERectangle 4
600
601
602
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
603
 * Hextile Encoding.  The rectangle is divided up into "tiles" of 16x16 pixels,
604
 * starting at the top left going in left-to-right, top-to-bottom order.  If
605
 * the width of the rectangle is not an exact multiple of 16 then the width of
606
 * the last tile in each row will be correspondingly smaller.  Similarly if the
607
 * height is not an exact multiple of 16 then the height of each tile in the
608
 * final row will also be smaller.  Each tile begins with a "subencoding" type
609
 * byte, which is a mask made up of a number of bits.  If the Raw bit is set
610
 * then the other bits are irrelevant; w*h pixel values follow (where w and h
611
 * are the width and height of the tile).  Otherwise the tile is encoded in a
612
 * similar way to RRE, except that the position and size of each subrectangle
613
 * can be specified in just two bytes.  The other bits in the mask are as
614
 * follows:
615
 *
616
 * BackgroundSpecified - if set, a pixel value follows which specifies
617
 *    the background colour for this tile.  The first non-raw tile in a
618
 *    rectangle must have this bit set.  If this bit isn't set then the
619
 *    background is the same as the last tile.
620
 *
621
 * ForegroundSpecified - if set, a pixel value follows which specifies
622
 *    the foreground colour to be used for all subrectangles in this tile.
623
 *    If this bit is set then the SubrectsColoured bit must be zero.
624
 *
625
 * AnySubrects - if set, a single byte follows giving the number of
626
 *    subrectangles following.  If not set, there are no subrectangles (i.e.
627
 *    the whole tile is just solid background colour).
628
 *
629
 * SubrectsColoured - if set then each subrectangle is preceded by a pixel
630
 *    value giving the colour of that subrectangle.  If not set, all
631
 *    subrectangles are the same colour, the foreground colour;  if the
632
 *    ForegroundSpecified bit wasn't set then the foreground is the same as
633
 *    the last tile.
634
 *
635
 * The position and size of each subrectangle is specified in two bytes.  The
636
 * Pack macros below can be used to generate the two bytes from x, y, w, h,
637
 * and the Extract macros can be used to extract the x, y, w, h values from
638
 * the two bytes.
639
 */
640
641
#define rfbHextileRaw			(1 << 0)
642
#define rfbHextileBackgroundSpecified	(1 << 1)
643
#define rfbHextileForegroundSpecified	(1 << 2)
644
#define rfbHextileAnySubrects		(1 << 3)
645
#define rfbHextileSubrectsColoured	(1 << 4)
646
647
#define rfbHextilePackXY(x,y) (((x) << 4) | (y))
648
#define rfbHextilePackWH(w,h) ((((w)-1) << 4) | ((h)-1))
649
#define rfbHextileExtractX(byte) ((byte) >> 4)
650
#define rfbHextileExtractY(byte) ((byte) & 0xf)
651
#define rfbHextileExtractW(byte) (((byte) >> 4) + 1)
652
#define rfbHextileExtractH(byte) (((byte) & 0xf) + 1)
653
654
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
655
 * ZLIB - zlib compression Encoding.  We have an rfbZlibHeader structure
656
 * giving the number of bytes to follow.  Finally the data follows in
657
 * zlib compressed format.
658
 */
659
660
typedef struct _rfbZlibHeader {
661
    CARD32 nBytes;
662
} rfbZlibHeader;
663
664
#define sz_rfbZlibHeader 4
665
666
667
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
668
 * Tight Encoding.
669
 *
670
 *-- The first byte of each Tight-encoded rectangle is a "compression control
671
 *   byte". Its format is as follows (bit 0 is the least significant one):
672
 *
673
 *   bit 0:    if 1, then compression stream 0 should be reset;
674
 *   bit 1:    if 1, then compression stream 1 should be reset;
675
 *   bit 2:    if 1, then compression stream 2 should be reset;
676
 *   bit 3:    if 1, then compression stream 3 should be reset;
677
 *   bits 7-4: if 1000 (0x08), then the compression type is "fill",
678
 *             if 1001 (0x09), then the compression type is "jpeg",
679
 *             if 0xxx, then the compression type is "basic",
680
 *             values greater than 1001 are not valid.
681
 *
682
 * If the compression type is "basic", then bits 6..4 of the
683
 * compression control byte (those xxx in 0xxx) specify the following:
684
 *
685
 *   bits 5-4:  decimal representation is the index of a particular zlib
686
 *              stream which should be used for decompressing the data;
687
 *   bit 6:     if 1, then a "filter id" byte is following this byte.
688
 *
689
 *-- The data that follows after the compression control byte described
690
 * above depends on the compression type ("fill", "jpeg" or "basic").
691
 *
692
 *-- If the compression type is "fill", then the only pixel value follows, in
693
 * client pixel format (see NOTE 1). This value applies to all pixels of the
694
 * rectangle.
695
 *
696
 *-- If the compression type is "jpeg", the following data stream looks like
697
 * this:
698
 *
699
 *   1..3 bytes:  data size (N) in compact representation;
700
 *   N bytes:     JPEG image.
701
 *
702
 * Data size is compactly represented in one, two or three bytes, according
703
 * to the following scheme:
704
 *
705
 *  0xxxxxxx                    (for values 0..127)
706
 *  1xxxxxxx 0yyyyyyy           (for values 128..16383)
707
 *  1xxxxxxx 1yyyyyyy zzzzzzzz  (for values 16384..4194303)
708
 *
709
 * Here each character denotes one bit, xxxxxxx are the least significant 7
710
 * bits of the value (bits 0-6), yyyyyyy are bits 7-13, and zzzzzzzz are the
711
 * most significant 8 bits (bits 14-21). For example, decimal value 10000
712
 * should be represented as two bytes: binary 10010000 01001110, or
713
 * hexadecimal 90 4E.
714
 *
715
 *-- If the compression type is "basic" and bit 6 of the compression control
716
 * byte was set to 1, then the next (second) byte specifies "filter id" which
717
 * tells the decoder what filter type was used by the encoder to pre-process
718
 * pixel data before the compression. The "filter id" byte can be one of the
719
 * following:
720
 *
721
 *   0:  no filter ("copy" filter);
722
 *   1:  "palette" filter;
723
 *   2:  "gradient" filter.
724
 *
725
 *-- If bit 6 of the compression control byte is set to 0 (no "filter id"
726
 * byte), or if the filter id is 0, then raw pixel values in the client
727
 * format (see NOTE 1) will be compressed. See below details on the
728
 * compression.
729
 *
730
 *-- The "gradient" filter pre-processes pixel data with a simple algorithm
731
 * which converts each color component to a difference between a "predicted"
732
 * intensity and the actual intensity. Such a technique does not affect
733
 * uncompressed data size, but helps to compress photo-like images better. 
734
 * Pseudo-code for converting intensities to differences is the following:
735
 *
736
 *   P[i,j] := V[i-1,j] + V[i,j-1] - V[i-1,j-1];
737
 *   if (P[i,j] < 0) then P[i,j] := 0;
738
 *   if (P[i,j] > MAX) then P[i,j] := MAX;
739
 *   D[i,j] := V[i,j] - P[i,j];
740
 *
741
 * Here V[i,j] is the intensity of a color component for a pixel at
742
 * coordinates (i,j). MAX is the maximum value of intensity for a color
743
 * component.
744
 *
745
 *-- The "palette" filter converts true-color pixel data to indexed colors
746
 * and a palette which can consist of 2..256 colors. If the number of colors
747
 * is 2, then each pixel is encoded in 1 bit, otherwise 8 bits is used to
748
 * encode one pixel. 1-bit encoding is performed such way that the most
749
 * significant bits correspond to the leftmost pixels, and each raw of pixels
750
 * is aligned to the byte boundary. When "palette" filter is used, the
751
 * palette is sent before the pixel data. The palette begins with an unsigned
752
 * byte which value is the number of colors in the palette minus 1 (i.e. 1
753
 * means 2 colors, 255 means 256 colors in the palette). Then follows the
754
 * palette itself which consist of pixel values in client pixel format (see
755
 * NOTE 1).
756
 *
757
 *-- The pixel data is compressed using the zlib library. But if the data
758
 * size after applying the filter but before the compression is less then 12,
759
 * then the data is sent as is, uncompressed. Four separate zlib streams
760
 * (0..3) can be used and the decoder should read the actual stream id from
761
 * the compression control byte (see NOTE 2).
762
 *
763
 * If the compression is not used, then the pixel data is sent as is,
764
 * otherwise the data stream looks like this:
765
 *
766
 *   1..3 bytes:  data size (N) in compact representation;
767
 *   N bytes:     zlib-compressed data.
768
 *
769
 * Data size is compactly represented in one, two or three bytes, just like
770
 * in the "jpeg" compression method (see above).
771
 *
772
 *-- NOTE 1. If the color depth is 24, and all three color components are
773
 * 8-bit wide, then one pixel in Tight encoding is always represented by
774
 * three bytes, where the first byte is red component, the second byte is
775
 * green component, and the third byte is blue component of the pixel color
776
 * value. This applies to colors in palettes as well.
777
 *
778
 *-- NOTE 2. The decoder must reset compression streams' states before
779
 * decoding the rectangle, if some of bits 0,1,2,3 in the compression control
780
 * byte are set to 1. Note that the decoder must reset zlib streams even if
781
 * the compression type is "fill" or "jpeg".
782
 *
783
 *-- NOTE 3. The "gradient" filter and "jpeg" compression may be used only
784
 * when bits-per-pixel value is either 16 or 32, not 8.
785
 *
786
 *-- NOTE 4. The width of any Tight-encoded rectangle cannot exceed 2048
787
 * pixels. If a rectangle is wider, it must be split into several rectangles
788
 * and each one should be encoded separately.
789
 *
790
 */
791
792
#define rfbTightExplicitFilter         0x04
793
#define rfbTightFill                   0x08
794
#define rfbTightJpeg                   0x09
795
#define rfbTightMaxSubencoding         0x09
796
797
/* Filters to improve compression efficiency */
798
#define rfbTightFilterCopy             0x00
799
#define rfbTightFilterPalette          0x01
800
#define rfbTightFilterGradient         0x02
801
802
803
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
804
 * ZLIBHEX - zlib compressed Hextile Encoding.  Essentially, this is the
805
 * hextile encoding with zlib compression on the tiles that can not be
806
 * efficiently encoded with one of the other hextile subencodings.  The
807
 * new zlib subencoding uses two bytes to specify the length of the
808
 * compressed tile and then the compressed data follows.  As with the
809
 * raw sub-encoding, the zlib subencoding invalidates the other
810
 * values, if they are also set.
811
 */
812
813
#define rfbHextileZlibRaw		(1 << 5)
814
#define rfbHextileZlibHex		(1 << 6)
815
816
817
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
818
 * XCursor encoding. This is a special encoding used to transmit X-style
819
 * cursor shapes from server to clients. Note that for this encoding,
820
 * coordinates in rfbFramebufferUpdateRectHeader structure hold hotspot
821
 * position (r.x, r.y) and cursor size (r.w, r.h). If (w * h != 0), two RGB
822
 * samples are sent after header in the rfbXCursorColors structure. They
823
 * denote foreground and background colors of the cursor. If a client
824
 * supports only black-and-white cursors, it should ignore these colors and
825
 * assume that foreground is black and background is white. Next, two bitmaps
826
 * (1 bits per pixel) follow: first one with actual data (value 0 denotes
827
 * background color, value 1 denotes foreground color), second one with
828
 * transparency data (bits with zero value mean that these pixels are
829
 * transparent). Both bitmaps represent cursor data in a byte stream, from
830
 * left to right, from top to bottom, and each row is byte-aligned. Most
831
 * significant bits correspond to leftmost pixels. The number of bytes in
832
 * each row can be calculated as ((w + 7) / 8). If (w * h == 0), cursor
833
 * should be hidden (or default local cursor should be set by the client).
834
 */
835
836
typedef struct _rfbXCursorColors {
837
    CARD8 foreRed;
838
    CARD8 foreGreen;
839
    CARD8 foreBlue;
840
    CARD8 backRed;
841
    CARD8 backGreen;
842
    CARD8 backBlue;
843
} rfbXCursorColors;
844
845
#define sz_rfbXCursorColors 6
846
847
848
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
849
 * RichCursor encoding. This is a special encoding used to transmit cursor
850
 * shapes from server to clients. It is similar to the XCursor encoding but
851
 * uses client pixel format instead of two RGB colors to represent cursor
852
 * image. For this encoding, coordinates in rfbFramebufferUpdateRectHeader
853
 * structure hold hotspot position (r.x, r.y) and cursor size (r.w, r.h).
854
 * After header, two pixmaps follow: first one with cursor image in current
855
 * client pixel format (like in raw encoding), second with transparency data
856
 * (1 bit per pixel, exactly the same format as used for transparency bitmap
857
 * in the XCursor encoding). If (w * h == 0), cursor should be hidden (or
858
 * default local cursor should be set by the client).
859
 */
860
861
862
/*-----------------------------------------------------------------------------
863
 * SetColourMapEntries - these messages are only sent if the pixel
864
 * format uses a "colour map" (i.e. trueColour false) and the client has not
865
 * fixed the entire colour map using FixColourMapEntries.  In addition they
866
 * will only start being sent after the client has sent its first
867
 * FramebufferUpdateRequest.  So if the client always tells the server to use
868
 * trueColour then it never needs to process this type of message.
869
 */
870
871
typedef struct _rfbSetColourMapEntriesMsg {
872
    CARD8 type;			/* always rfbSetColourMapEntries */
873
    CARD8 redIndex;		/* used to be pad, but used for DirectColor */
874
    CARD16 firstColour;
875
    CARD16 nColours;
876
877
    /* Followed by nColours * 3 * CARD16
878
       r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */
879
880
} rfbSetColourMapEntriesMsg;
881
882
#define sz_rfbSetColourMapEntriesMsg 6
883
884
885
886
/*-----------------------------------------------------------------------------
887
 * Bell - ring a bell on the client if it has one.
888
 */
889
890
typedef struct _rfbBellMsg {
891
    CARD8 type;			/* always rfbBell */
892
} rfbBellMsg;
893
894
#define sz_rfbBellMsg 1
895
896
897
898
/*-----------------------------------------------------------------------------
899
 * ServerCutText - the server has new text in its cut buffer.
900
 */
901
902
typedef struct _rfbServerCutTextMsg {
903
    CARD8 type;			/* always rfbServerCutText */
904
    CARD8 pad1;
905
    CARD16 pad2;
906
    CARD32 length;
907
    /* followed by char text[length] */
908
} rfbServerCutTextMsg;
909
910
#define sz_rfbServerCutTextMsg 8
911
912
/*-----------------------------------------------------------------------------
913
 * ChromiumStart - a port number for the crserver
914
 */
915
916
typedef struct {
917
    CARD8 type;			/* always rfbChromiumStart */
918
    CARD8 pad1;
919
    CARD16 pad2;
920
    CARD32 crServerPort;
921
    CARD32 mothershipPort;
922
} rfbChromiumStartMsg;
923
924
#define sz_rfbChromiumStartMsg 12
925
926
927
/*-----------------------------------------------------------------------------
928
 * ChromiumMoveResizeWindow - move a chromium window
929
 */
930
931
typedef struct {
932
    CARD8 type;			/* always rfbChromiumMoveResizeWindow */
933
    CARD8 pad1;
934
    CARD16 pad2;
935
    CARD32 winid;
936
    CARD32 x;
937
    CARD32 y;
938
    CARD32 w;
939
    CARD32 h;
940
} rfbChromiumMoveResizeWindowMsg;
941
942
#define sz_rfbChromiumMoveResizeWindowMsg 24
943
944
/*-----------------------------------------------------------------------------
945
 * ChromiumClipList - send clip list
946
 */
947
948
typedef struct {
949
    CARD8 type;			/* always rfbChromiumClipList */
950
    CARD8 pad1;
951
    CARD16 pad2;
952
    CARD32 winid;
953
    CARD32 length;
954
} rfbChromiumClipListMsg;
955
956
#define sz_rfbChromiumClipListMsg 12
957
958
/*-----------------------------------------------------------------------------
959
 * ChromiumWindowShow - map or unmap a window
960
 */
961
962
typedef struct {
963
    CARD8 type;			/* always rfbChromiumWindowShow */
964
    CARD8 pad1;
965
    CARD16 pad2;
966
    CARD32 winid;
967
    CARD32 show;
968
} rfbChromiumWindowShowMsg;
969
970
#define sz_rfbChromiumWindowShowMsg 12
971
972
/*-----------------------------------------------------------------------------
973
 * ChromiumWindowDestroy - destroy a window
974
 */
975
976
typedef struct {
977
    CARD8 type;			/* always rfbChromiumWindowDestroy */
978
    CARD8 pad1;
979
    CARD16 pad2;
980
    CARD32 winid;
981
} rfbChromiumWindowDestroyMsg;
982
983
#define sz_rfbChromiumWindowDestroyMsg 8
984
985
/*-----------------------------------------------------------------------------
986
 * FileListData
987
 */
988
989
typedef struct _rfbFileListDataMsg {
990
    CARD8 type;
991
    CARD8 flags;
992
    CARD16 numFiles;
993
    CARD16 dataSize;
994
    CARD16 compressedSize;
995
    /* Followed by SizeData[numFiles] */
996
    /* Followed by Filenames[compressedSize] */
997
} rfbFileListDataMsg;
998
999
#define sz_rfbFileListDataMsg 8
1000
1001
/*-----------------------------------------------------------------------------
1002
 * FileDownloadData
1003
 */
1004
1005
typedef struct _rfbFileDownloadDataMsg {
1006
    CARD8 type;
1007
    CARD8 compressLevel;
1008
    CARD16 realSize;
1009
    CARD16 compressedSize;
1010
    /* Followed by File[copressedSize] */
1011
} rfbFileDownloadDataMsg;
1012
1013
#define sz_rfbFileDownloadDataMsg 6
1014
1015
1016
/*-----------------------------------------------------------------------------
1017
 * FileUploadCancel
1018
 */
1019
1020
typedef struct _rfbFileUploadCancelMsg {
1021
    CARD8 type;
1022
    CARD8 unused;
1023
    CARD16 reasonLen;
1024
    /* Followed by reason[reasonLen] */
1025
} rfbFileUploadCancelMsg;
1026
1027
#define sz_rfbFileUploadCancelMsg 4
1028
1029
/*-----------------------------------------------------------------------------
1030
 * FileDownloadFailed
1031
 */
1032
1033
typedef struct _rfbFileDownloadFailedMsg {
1034
    CARD8 type;
1035
    CARD8 unused;
1036
    CARD16 reasonLen;
1037
    /* Followed by reason[reasonLen] */
1038
} rfbFileDownloadFailedMsg;
1039
1040
#define sz_rfbFileDownloadFailedMsg 4
1041
1042
/*-----------------------------------------------------------------------------
1043
 * Union of all server->client messages.
1044
 */
1045
1046
typedef union _rfbServerToClientMsg {
1047
    CARD8 type;
1048
    rfbFramebufferUpdateMsg fu;
1049
    rfbSetColourMapEntriesMsg scme;
1050
    rfbBellMsg b;
1051
    rfbServerCutTextMsg sct;
1052
    rfbFileListDataMsg fld;
1053
    rfbFileDownloadDataMsg fdd;
1054
    rfbFileUploadCancelMsg fuc;
1055
    rfbFileDownloadFailedMsg fdf;
1056
    rfbChromiumStartMsg scd;
1057
    rfbChromiumMoveResizeWindowMsg scm;
1058
    rfbChromiumClipListMsg sccl;
1059
    rfbChromiumWindowShowMsg scws;
1060
    rfbChromiumWindowDestroyMsg scwd;
1061
} rfbServerToClientMsg;
1062
1063
1064
1065
/*****************************************************************************
1066
 *
1067
 * Message definitions (client -> server)
1068
 *
1069
 *****************************************************************************/
1070
1071
1072
/*-----------------------------------------------------------------------------
1073
 * SetPixelFormat - tell the RFB server the format in which the client wants
1074
 * pixels sent.
1075
 */
1076
1077
typedef struct _rfbSetPixelFormatMsg {
1078
    CARD8 type;			/* always rfbSetPixelFormat */
1079
    CARD8 pad1;
1080
    CARD16 pad2;
1081
    rfbPixelFormat format;
1082
} rfbSetPixelFormatMsg;
1083
1084
#define sz_rfbSetPixelFormatMsg (sz_rfbPixelFormat + 4)
1085
1086
1087
/*-----------------------------------------------------------------------------
1088
 * FixColourMapEntries - when the pixel format uses a "colour map", fix
1089
 * read-only colour map entries.
1090
 *
1091
 *    ***************** NOT CURRENTLY SUPPORTED *****************
1092
 */
1093
1094
typedef struct _rfbFixColourMapEntriesMsg {
1095
    CARD8 type;			/* always rfbFixColourMapEntries */
1096
    CARD8 pad;
1097
    CARD16 firstColour;
1098
    CARD16 nColours;
1099
1100
    /* Followed by nColours * 3 * CARD16
1101
       r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */
1102
1103
} rfbFixColourMapEntriesMsg;
1104
1105
#define sz_rfbFixColourMapEntriesMsg 6
1106
1107
1108
/*-----------------------------------------------------------------------------
1109
 * SetEncodings - tell the RFB server which encoding types we accept.  Put them
1110
 * in order of preference, if we have any.  We may always receive raw
1111
 * encoding, even if we don't specify it here.
1112
 */
1113
1114
typedef struct _rfbSetEncodingsMsg {
1115
    CARD8 type;			/* always rfbSetEncodings */
1116
    CARD8 pad;
1117
    CARD16 nEncodings;
1118
    /* followed by nEncodings * CARD32 encoding types */
1119
} rfbSetEncodingsMsg;
1120
1121
#define sz_rfbSetEncodingsMsg 4
1122
1123
1124
/*-----------------------------------------------------------------------------
1125
 * FramebufferUpdateRequest - request for a framebuffer update.  If incremental
1126
 * is true then the client just wants the changes since the last update.  If
1127
 * false then it wants the whole of the specified rectangle.
1128
 */
1129
1130
typedef struct _rfbFramebufferUpdateRequestMsg {
1131
    CARD8 type;			/* always rfbFramebufferUpdateRequest */
1132
    CARD8 incremental;
1133
    CARD16 x;
1134
    CARD16 y;
1135
    CARD16 w;
1136
    CARD16 h;
1137
} rfbFramebufferUpdateRequestMsg;
1138
1139
#define sz_rfbFramebufferUpdateRequestMsg 10
1140
1141
1142
/*-----------------------------------------------------------------------------
1143
 * KeyEvent - key press or release
1144
 *
1145
 * Keys are specified using the "keysym" values defined by the X Window System.
1146
 * For most ordinary keys, the keysym is the same as the corresponding ASCII
1147
 * value.  Other common keys are:
1148
 *
1149
 * BackSpace		0xff08
1150
 * Tab			0xff09
1151
 * Return or Enter	0xff0d
1152
 * Escape		0xff1b
1153
 * Insert		0xff63
1154
 * Delete		0xffff
1155
 * Home			0xff50
1156
 * End			0xff57
1157
 * Page Up		0xff55
1158
 * Page Down		0xff56
1159
 * Left			0xff51
1160
 * Up			0xff52
1161
 * Right		0xff53
1162
 * Down			0xff54
1163
 * F1			0xffbe
1164
 * F2			0xffbf
1165
 * ...			...
1166
 * F12			0xffc9
1167
 * Shift		0xffe1
1168
 * Control		0xffe3
1169
 * Meta			0xffe7
1170
 * Alt			0xffe9
1171
 */
1172
1173
typedef struct _rfbKeyEventMsg {
1174
    CARD8 type;			/* always rfbKeyEvent */
1175
    CARD8 down;			/* true if down (press), false if up */
1176
    CARD16 pad;
1177
    CARD32 key;			/* key is specified as an X keysym */
1178
} rfbKeyEventMsg;
1179
1180
#define sz_rfbKeyEventMsg 8
1181
1182
1183
/*-----------------------------------------------------------------------------
1184
 * PointerEvent - mouse/pen move and/or button press.
1185
 */
1186
1187
typedef struct _rfbPointerEventMsg {
1188
    CARD8 type;			/* always rfbPointerEvent */
1189
    CARD8 buttonMask;		/* bits 0-7 are buttons 1-8, 0=up, 1=down */
1190
    CARD16 x;
1191
    CARD16 y;
1192
} rfbPointerEventMsg;
1193
1194
#define rfbButton1Mask 1
1195
#define rfbButton2Mask 2
1196
#define rfbButton3Mask 4
1197
#define rfbButton4Mask 8
1198
#define rfbButton5Mask 16
1199
1200
#define sz_rfbPointerEventMsg 6
1201
1202
1203
1204
/*-----------------------------------------------------------------------------
1205
 * ClientCutText - the client has new text in its cut buffer.
1206
 */
1207
1208
typedef struct _rfbClientCutTextMsg {
1209
    CARD8 type;			/* always rfbClientCutText */
1210
    CARD8 pad1;
1211
    CARD16 pad2;
1212
    CARD32 length;
1213
    /* followed by char text[length] */
1214
} rfbClientCutTextMsg;
1215
1216
#define sz_rfbClientCutTextMsg 8
1217
1218
/*-----------------------------------------------------------------------------
1219
 * FileListRequest
1220
 */
1221
1222
typedef struct _rfbFileListRequestMsg {
1223
    CARD8 type;
1224
    CARD8 flags;
1225
    CARD16 dirNameSize;
1226
    /* Followed by char Dirname[dirNameSize] */
1227
} rfbFileListRequestMsg;
1228
1229
#define sz_rfbFileListRequestMsg 4
1230
1231
/*-----------------------------------------------------------------------------
1232
 * FileDownloadRequest
1233
 */
1234
1235
typedef struct _rfbFileDownloadRequestMsg {
1236
    CARD8 type;
1237
    CARD8 compressedLevel;
1238
    CARD16 fNameSize;
1239
    CARD32 position;
1240
    /* Followed by char Filename[fNameSize] */
1241
} rfbFileDownloadRequestMsg;
1242
1243
#define sz_rfbFileDownloadRequestMsg 8
1244
1245
/*-----------------------------------------------------------------------------
1246
 * FileUploadRequest
1247
 */
1248
1249
typedef struct _rfbFileUploadRequestMsg {
1250
    CARD8 type;
1251
    CARD8 compressedLevel;
1252
    CARD16 fNameSize;
1253
    CARD32 position;
1254
    /* Followed by char Filename[fNameSize] */
1255
} rfbFileUploadRequestMsg;
1256
1257
#define sz_rfbFileUploadRequestMsg 8
1258
1259
1260
/*-----------------------------------------------------------------------------
1261
 * FileUploadData
1262
 */
1263
1264
typedef struct _rfbFileUploadDataMsg {
1265
    CARD8 type;
1266
    CARD8 compressedLevel;
1267
    CARD16 realSize;
1268
    CARD16 compressedSize;
1269
    /* Followed by File[compressedSize]   */
1270
} rfbFileUploadDataMsg;
1271
1272
#define sz_rfbFileUploadDataMsg 8
1273
1274
/*-----------------------------------------------------------------------------
1275
 * FileDownloadCancel
1276
 */
1277
1278
typedef struct _rfbFileDownloadCancelMsg {
1279
    CARD8 type;
1280
    CARD8 unused;
1281
    CARD16 reasonLen;
1282
    /* Followed by reason[reasonLen] */
1283
} rfbFileDownloadCancelMsg;
1284
1285
#define sz_rfbFileDownloadCancelMsg 4
1286
1287
/*-----------------------------------------------------------------------------
1288
 * FileUploadFailed
1289
 */
1290
1291
typedef struct _rfbFileUploadFailedMsg {
1292
    CARD8 type;
1293
    CARD8 unused;
1294
    CARD16 reasonLen;
1295
    /* Followed by reason[reasonLen] */
1296
} rfbFileUploadFailedMsg;
1297
1298
#define sz_rfbFileUploadFailedMsg 4
1299
1300
/*-----------------------------------------------------------------------------
1301
 * FileCreateDirRequest
1302
 */
1303
1304
typedef struct _rfbFileCreateDirRequestMsg {
1305
    CARD8 type;
1306
    CARD8 unused;
1307
    CARD16 dNameLen;
1308
    CARD32 dModTime;
1309
    /* Followed by dName[dNameLen] */
1310
} rfbFileCreateDirRequestMsg;
1311
 
1312
#define sz_rfbFileCreateDirRequestMsg 8
1313
 
1314
/*-----------------------------------------------------------------------------
1315
 * ChromiumStop - the client has stopped the GL app.
1316
 */
1317
1318
typedef struct {
1319
    CARD8 type;			/* always rfbChromiumStop */
1320
    CARD8 pad1;
1321
    CARD16 pad2;
1322
    CARD32 port;
1323
} rfbChromiumStopMsg;
1324
1325
#define sz_rfbChromiumStopMsg 8
1326
1327
/*-----------------------------------------------------------------------------
1328
 * ChromiumExpose - redraw the window
1329
 */
1330
1331
typedef struct {
1332
    CARD8 type;			/* always rfbChromiumExpose */
1333
    CARD8 pad1;
1334
    CARD16 pad2;
1335
    CARD32 winid;
1336
} rfbChromiumExposeMsg;
1337
1338
#define sz_rfbChromiumExposeMsg 8
1339
1340
/*-----------------------------------------------------------------------------
1341
 * Union of all client->server messages.
1342
 */
1343
1344
typedef union _rfbClientToServerMsg {
1345
    CARD8 type;
1346
    rfbSetPixelFormatMsg spf;
1347
    rfbFixColourMapEntriesMsg fcme;
1348
    rfbSetEncodingsMsg se;
1349
    rfbFramebufferUpdateRequestMsg fur;
1350
    rfbKeyEventMsg ke;
1351
    rfbPointerEventMsg pe;
1352
    rfbClientCutTextMsg cct;
1353
    rfbFileListRequestMsg flr;
1354
    rfbFileDownloadRequestMsg fdr;
1355
    rfbFileUploadRequestMsg fupr;
1356
    rfbFileUploadDataMsg fud;
1357
    rfbFileDownloadCancelMsg fdc;
1358
    rfbFileUploadFailedMsg fuf;
1359
    rfbFileCreateDirRequestMsg fcdr;
1360
    rfbChromiumStopMsg csd;
1361
    rfbChromiumExposeMsg cse;
1362
} rfbClientToServerMsg;
(-)xorg-server-1.4.orig/hw/vnc/rfbserver.c (+2308 lines)
Line 0 Link Here
1
/*
2
 * rfbserver.c - deal with server-side of the RFB protocol.
3
 *
4
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
5
 */
6
7
/*
8
 *  Copyright (C) 2000-2004 Constantin Kaplinsky.  All Rights Reserved.
9
 *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
10
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
11
 *
12
 *  This is free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 2 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  This software is distributed in the hope that it will be useful,
18
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 *  GNU General Public License for more details.
21
 *
22
 *  You should have received a copy of the GNU General Public License
23
 *  along with this software; if not, write to the Free Software
24
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
25
 *  USA.
26
 */
27
28
/* Use ``#define CORBA'' to enable CORBA control interface */
29
#ifdef HAVE_DIX_CONFIG_H
30
#include <dix-config.h>
31
#endif
32
33
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <unistd.h>
37
#include <pwd.h>
38
#include <sys/types.h>
39
#include <sys/socket.h>
40
#include <netinet/in.h>
41
#include <arpa/inet.h>
42
#include "input.h"
43
#include "mipointer.h"
44
#if XFREE86VNC
45
#include <micmap.h>
46
#endif
47
#ifdef CHROMIUM
48
#include "mivalidate.h"
49
#endif
50
#include "rfb.h"
51
#include "windowstr.h"
52
#include "sprite.h"
53
#include "propertyst.h"
54
#include <X11/Xatom.h>
55
#include <mi.h>
56
57
#ifdef CORBA
58
#include <vncserverctrl.h>
59
#endif
60
61
#ifdef CHROMIUM
62
struct CRWindowTable *windowTable = NULL;
63
#endif
64
65
extern Atom VNC_CONNECT;
66
67
rfbClientPtr rfbClientHead = NULL;  /* list of all VNC clients/viewers */
68
rfbClientPtr pointerClient = NULL;  /* Mutex for pointer events */
69
70
static rfbClientPtr rfbNewClient(ScreenPtr pScreen, int sock);
71
static void rfbProcessClientProtocolVersion(rfbClientPtr cl);
72
static void rfbProcessClientInitMessage(rfbClientPtr cl);
73
static void rfbSendInteractionCaps(rfbClientPtr cl);
74
static void rfbProcessClientNormalMessage(rfbClientPtr cl);
75
static Bool rfbSendCopyRegion(rfbClientPtr cl, RegionPtr reg, int dx, int dy);
76
static Bool rfbSendLastRectMarker(rfbClientPtr cl);
77
78
static char *text = NULL;
79
80
void
81
rfbRootPropertyChange(ScreenPtr pScreen)
82
{
83
    PropertyPtr pProp;
84
    WindowPtr pWin = WindowTable[pScreen->myNum];
85
86
    pProp = wUserProps (pWin);
87
88
    while (pProp) {
89
        if ((pProp->propertyName == XA_CUT_BUFFER0) && 
90
	    (pProp->type == XA_STRING) &&
91
	    (pProp->format == 8))
92
    	{
93
	    /* Ensure we don't keep re-sending cut buffer */
94
95
    	    if ( (text && pProp->data && strncmp(text, pProp->data, pProp->size)) || !text)
96
	    	rfbGotXCutText(pProp->data, pProp->size);
97
98
	    if (text) xfree(text);
99
    	    text = xalloc(1 + pProp->size);
100
    	    if (! text) return;
101
    	    if (pProp->data) memcpy(text, pProp->data, pProp->size);
102
    	    text[pProp->size] = '\0';
103
104
	    return;
105
    	}
106
    	if ((pProp->propertyName == VNC_CONNECT) && (pProp->type == XA_STRING)
107
	    && (pProp->format == 8) && (pProp->size > 0))
108
    	{
109
	    int i;
110
	    rfbClientPtr cl;
111
	    int port = 5500;
112
	    char *host = (char *)Xalloc(pProp->size+1);
113
	    memcpy(host, pProp->data, pProp->size);
114
	    host[pProp->size] = 0;
115
	    for (i = 0; i < pProp->size; i++) {
116
	    	if (host[i] == ':') {
117
		    port = atoi(&host[i+1]);
118
		    host[i] = 0;
119
	    	}
120
	    }
121
122
	    cl = rfbReverseConnection(pScreen, host, port);
123
124
#ifdef CORBA
125
	    if (cl != NULL)
126
	    	newConnection(cl, (KEYBOARD_DEVICE|POINTER_DEVICE), 1, 1, 1);
127
#endif
128
129
	    ChangeWindowProperty(pWin,
130
		 	     pProp->propertyName, pProp->type,
131
			     pProp->format, PropModeReplace,
132
			     0, NULL,
133
			     FALSE
134
			     );
135
136
	    free(host);
137
    	}
138
	pProp = pProp->next;
139
    }
140
}
141
142
int
143
rfbBitsPerPixel(depth)
144
    int depth;
145
{
146
    if (depth == 1) return 1;
147
    else if (depth <= 8) return 8;
148
    else if (depth <= 16) return 16;
149
    else return 32;
150
}
151
152
void 
153
rfbUserAllow(int sock, int accept)
154
{
155
    rfbClientPtr cl;
156
157
    for (cl = rfbClientHead; cl; cl = cl->next) {
158
	if (cl->sock == sock) {
159
	    cl->userAccepted = accept;
160
	}
161
    }
162
}
163
164
/*
165
 * rfbNewClientConnection is called from sockets.c when a new connection
166
 * comes in.
167
 */
168
169
void
170
rfbNewClientConnection(ScreenPtr pScreen, int sock)
171
{
172
    rfbClientPtr cl;
173
174
    cl = rfbNewClient(pScreen, sock);
175
176
    GenerateVncConnectedEvent(sock);
177
178
#if XFREE86VNC
179
    /* Someone is connected - disable VT switching */
180
    xf86EnableVTSwitch(FALSE);
181
#endif
182
183
#ifdef CORBA
184
    if (cl != NULL)
185
	newConnection(cl, (KEYBOARD_DEVICE|POINTER_DEVICE), 1, 1, 1);
186
#endif
187
}
188
189
190
/*
191
 * rfbReverseConnection is called by the CORBA stuff to make an outward
192
 * connection to a "listening" RFB client.
193
 */
194
195
rfbClientPtr
196
rfbReverseConnection(ScreenPtr pScreen, char *host, int port)
197
{
198
    int sock;
199
    rfbClientPtr cl;
200
201
    if ((sock = rfbConnect(pScreen, host, port)) < 0)
202
	return (rfbClientPtr)NULL;
203
204
    cl = rfbNewClient(pScreen, sock);
205
206
    if (cl) {
207
	cl->reverseConnection = TRUE;
208
    }
209
210
    return cl;
211
}
212
213
214
#ifdef CHROMIUM
215
/*
216
 * rfbSetClip --
217
 * 	Generate expose event.
218
 * 	This function is overkill and should be cleaned up, but it
219
 * 	works for now.
220
 */
221
222
void
223
rfbSetClip (WindowPtr pWin, BOOL enable)
224
{
225
    ScreenPtr   pScreen = pWin->drawable.pScreen;
226
    WindowPtr	pChild;
227
    Bool	WasViewable = (Bool)(pWin->viewable);
228
    Bool	anyMarked = FALSE;
229
    RegionPtr	pOldClip = NULL, bsExposed;
230
#ifdef DO_SAVE_UNDERS
231
    Bool	dosave = FALSE;
232
#endif
233
    WindowPtr   pLayerWin;
234
    BoxRec	box;
235
236
    if (WasViewable)
237
    {
238
	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
239
	{
240
	    (void) (*pScreen->MarkOverlappedWindows)(pChild,
241
						     pChild,
242
						     &pLayerWin);
243
	}
244
	(*pScreen->MarkWindow) (pWin);
245
	anyMarked = TRUE;
246
	if (pWin->valdata)
247
	{
248
	    if (HasBorder (pWin))
249
	    {
250
		RegionPtr	borderVisible;
251
252
		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
253
		REGION_SUBTRACT(pScreen, borderVisible,
254
				&pWin->borderClip, &pWin->winSize);
255
		pWin->valdata->before.borderVisible = borderVisible;
256
	    }
257
	    pWin->valdata->before.resized = TRUE;
258
	}
259
    }
260
    
261
    /*
262
     * Use REGION_BREAK to avoid optimizations in ValidateTree
263
     * that assume the root borderClip can't change well, normally
264
     * it doesn't...)
265
     */
266
    if (enable)
267
    {
268
	box.x1 = 0;
269
	box.y1 = 0;
270
	box.x2 = pScreen->width;
271
	box.y2 = pScreen->height;
272
	REGION_INIT (pScreen, &pWin->winSize, &box, 1);
273
	REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
274
	if (WasViewable)
275
	    REGION_RESET(pScreen, &pWin->borderClip, &box);
276
	pWin->drawable.width = pScreen->width;
277
	pWin->drawable.height = pScreen->height;
278
        REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
279
    }
280
    else
281
    {
282
	REGION_EMPTY(pScreen, &pWin->borderClip);
283
	REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
284
    }
285
    
286
    ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
287
    
288
    if (WasViewable)
289
    {
290
	if (pWin->backStorage)
291
	{
292
	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
293
	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
294
	}
295
296
	if (pWin->firstChild)
297
	{
298
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
299
							   pWin->firstChild,
300
							   (WindowPtr *)NULL);
301
	}
302
	else
303
	{
304
	    (*pScreen->MarkWindow) (pWin);
305
	    anyMarked = TRUE;
306
	}
307
308
#ifdef DO_SAVE_UNDERS
309
	if (DO_SAVE_UNDERS(pWin))
310
	{
311
	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
312
	}
313
#endif /* DO_SAVE_UNDERS */
314
315
	if (anyMarked)
316
	    (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
317
    }
318
319
    if (pWin->backStorage &&
320
	((pWin->backingStore == Always) || WasViewable))
321
    {
322
	if (!WasViewable)
323
	    pOldClip = &pWin->clipList; /* a convenient empty region */
324
	bsExposed = (*pScreen->TranslateBackingStore)
325
			     (pWin, 0, 0, pOldClip,
326
			      pWin->drawable.x, pWin->drawable.y);
327
	if (WasViewable)
328
	    REGION_DESTROY(pScreen, pOldClip);
329
	if (bsExposed)
330
	{
331
	    RegionPtr	valExposed = NullRegion;
332
    
333
	    if (pWin->valdata)
334
		valExposed = &pWin->valdata->after.exposed;
335
	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
336
	    if (valExposed)
337
		REGION_EMPTY(pScreen, valExposed);
338
	    REGION_DESTROY(pScreen, bsExposed);
339
	}
340
    }
341
    if (WasViewable)
342
    {
343
	if (anyMarked)
344
	    (*pScreen->HandleExposures)(pWin);
345
#ifdef DO_SAVE_UNDERS
346
	if (dosave)
347
	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
348
#endif /* DO_SAVE_UNDERS */
349
	if (anyMarked && pScreen->PostValidateTree)
350
	    (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
351
    }
352
    if (pWin->realized)
353
	WindowsRestructured ();
354
    FlushAllOutput ();
355
}
356
#endif /* CHROMIUM */
357
358
/*
359
 * rfbNewClient is called when a new connection has been made by whatever
360
 * means.
361
 */
362
363
static rfbClientPtr
364
rfbNewClient(ScreenPtr pScreen, int sock)
365
{
366
    rfbProtocolVersionMsg pv;
367
    rfbClientPtr cl;
368
    BoxRec box;
369
    struct sockaddr_in addr;
370
    SOCKLEN_T addrlen = sizeof(struct sockaddr_in);
371
    VNCSCREENPTR(pScreen);
372
    int i;
373
374
    if (rfbClientHead == NULL) {
375
	/* no other clients - make sure we don't think any keys are pressed */
376
	KbdReleaseAllKeys();
377
    } else {
378
	rfbLog("  (other clients");
379
	for (cl = rfbClientHead; cl; cl = cl->next) {
380
	    rfbLog(" %s",cl->host);
381
	}
382
	rfbLog(")\n");
383
    }
384
385
    cl = (rfbClientPtr)xalloc(sizeof(rfbClientRec));
386
387
#ifdef CHROMIUM
388
    cl->chromium_port = 0; /* no GL application on this port, yet */
389
#endif
390
    cl->userAccepted = 0; /* user hasn't even approached this yet .... */
391
    cl->sock = sock;
392
    getpeername(sock, (struct sockaddr *)&addr, &addrlen);
393
    cl->host = strdup(inet_ntoa(addr.sin_addr));
394
    cl->login = NULL;
395
396
    /* Dispatch client input to rfbProcessClientProtocolVersion(). */
397
    cl->state = RFB_PROTOCOL_VERSION;
398
399
    cl->viewOnly = FALSE;
400
    cl->reverseConnection = FALSE;
401
    cl->readyForSetColourMapEntries = FALSE;
402
    cl->useCopyRect = FALSE;
403
    cl->preferredEncoding = rfbEncodingRaw;
404
    cl->correMaxWidth = 48;
405
    cl->correMaxHeight = 48;
406
    cl->pScreen = pScreen;
407
408
    REGION_NULL(pScreen,&cl->copyRegion);
409
    cl->copyDX = 0;
410
    cl->copyDY = 0;
411
412
    box.x1 = box.y1 = 0;
413
    box.x2 = pVNC->width;
414
    box.y2 = pVNC->height;
415
    REGION_INIT(pScreen,&cl->modifiedRegion,&box,0);
416
417
    REGION_NULL(pScreen,&cl->requestedRegion);
418
419
    cl->deferredUpdateScheduled = FALSE;
420
    cl->deferredUpdateTimer = NULL;
421
422
    cl->format = pVNC->rfbServerFormat;
423
    cl->translateFn = rfbTranslateNone;
424
    cl->translateLookupTable = NULL;
425
426
    cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION;
427
    cl->tightQualityLevel = -1;
428
    for (i = 0; i < 4; i++)
429
        cl->zsActive[i] = FALSE;
430
431
    cl->enableCursorShapeUpdates = FALSE;
432
    cl->enableCursorPosUpdates = FALSE;
433
    cl->enableLastRectEncoding = FALSE;
434
#ifdef CHROMIUM
435
    cl->enableChromiumEncoding = FALSE;
436
#endif
437
438
    cl->next = rfbClientHead;
439
    rfbClientHead = cl;
440
441
    rfbResetStats(cl);
442
443
    cl->compStreamInited = FALSE;
444
    cl->compStream.total_in = 0;
445
    cl->compStream.total_out = 0;
446
    cl->compStream.zalloc = Z_NULL;
447
    cl->compStream.zfree = Z_NULL;
448
    cl->compStream.opaque = Z_NULL;
449
450
    cl->zlibCompressLevel = 5;
451
452
    sprintf(pv,rfbProtocolVersionFormat,rfbProtocolMajorVersion,
453
	    rfbProtocolMinorVersion);
454
455
    if (WriteExact(sock, pv, sz_rfbProtocolVersionMsg) < 0) {
456
	rfbLogPerror("rfbNewClient: write");
457
	rfbCloseSock(pScreen, sock);
458
	return NULL;
459
    }
460
461
    return cl;
462
}
463
464
465
/*
466
 * rfbClientConnectionGone is called from sockets.c just after a connection
467
 * has gone away.
468
 */
469
470
void
471
rfbClientConnectionGone(sock)
472
    int sock;
473
{
474
    rfbClientPtr cl, prev;
475
    int i;
476
#if XFREE86VNC
477
    int allowvt = TRUE;
478
#endif
479
480
    for (prev = NULL, cl = rfbClientHead; cl; prev = cl, cl = cl->next) {
481
	if (sock == cl->sock)
482
	    break;
483
    }
484
485
    if (!cl) {
486
	rfbLog("rfbClientConnectionGone: unknown socket %d\n",sock);
487
	return;
488
    }
489
490
    rfbLog("rfbClientConnectionGone\n");
491
492
    if (cl->login != NULL) {
493
	rfbLog("VNC Client %s (%s) gone\n", cl->login, cl->host);
494
	free(cl->login);
495
    } else {
496
	rfbLog("VNC Client %s gone\n", cl->host);
497
    }
498
    free(cl->host);
499
500
    /* Release the compression state structures if any. */
501
    if ( cl->compStreamInited == TRUE ) {
502
	deflateEnd( &(cl->compStream) );
503
    }
504
505
    for (i = 0; i < 4; i++) {
506
	if (cl->zsActive[i])
507
	    deflateEnd(&cl->zsStruct[i]);
508
    }
509
510
    if (pointerClient == cl)
511
	pointerClient = NULL;
512
513
#ifdef CORBA
514
    destroyConnection(cl);
515
#endif
516
517
    if (prev)
518
	prev->next = cl->next;
519
    else
520
	rfbClientHead = cl->next;
521
522
    REGION_UNINIT(cl->pScreen,&cl->copyRegion);
523
    REGION_UNINIT(cl->pScreen,&cl->modifiedRegion);
524
    TimerFree(cl->deferredUpdateTimer);
525
526
    rfbPrintStats(cl);
527
528
    if (cl->translateLookupTable) free(cl->translateLookupTable);
529
530
    xfree(cl);
531
532
    GenerateVncDisconnectedEvent(sock);
533
534
#if XFREE86VNC
535
    for (cl = rfbClientHead; cl; cl = cl->next) {
536
	/* still someone connected */
537
	allowvt = FALSE;
538
    }
539
540
    xf86EnableVTSwitch(allowvt);
541
#endif
542
}
543
544
545
/*
546
 * rfbProcessClientMessage is called when there is data to read from a client.
547
 */
548
549
void
550
rfbProcessClientMessage(ScreenPtr pScreen, int sock)
551
{
552
    rfbClientPtr cl;
553
554
    for (cl = rfbClientHead; cl; cl = cl->next) {
555
	if (sock == cl->sock)
556
	    break;
557
    }
558
559
    if (!cl) {
560
	rfbLog("rfbProcessClientMessage: unknown socket %d\n",sock);
561
	rfbCloseSock(pScreen, sock);
562
	return;
563
    }
564
565
#ifdef CORBA
566
    if (isClosePending(cl)) {
567
	rfbLog("Closing connection to client %s\n", cl->host);
568
	rfbCloseSock(pScreen, sock);
569
	return;
570
    }
571
#endif
572
573
    switch (cl->state) {
574
    case RFB_PROTOCOL_VERSION:
575
	rfbProcessClientProtocolVersion(cl);
576
	break;
577
    case RFB_SECURITY_TYPE:	/* protocol 3.7 */
578
	rfbProcessClientSecurityType(cl);
579
	break;
580
    case RFB_TUNNELING_TYPE:	/* protocol 3.7t */
581
	rfbProcessClientTunnelingType(cl);
582
	break;
583
    case RFB_AUTH_TYPE:		/* protocol 3.7t */
584
	rfbProcessClientAuthType(cl);
585
	break;
586
    case RFB_AUTHENTICATION:
587
	rfbVncAuthProcessResponse(cl);
588
	break;
589
    case RFB_INITIALISATION:
590
	rfbProcessClientInitMessage(cl);
591
	break;
592
    default:
593
	rfbProcessClientNormalMessage(cl);
594
    }
595
}
596
597
598
/*
599
 * rfbProcessClientProtocolVersion is called when the client sends its
600
 * protocol version.
601
 */
602
603
static void
604
rfbProcessClientProtocolVersion(cl)
605
    rfbClientPtr cl;
606
{
607
    rfbProtocolVersionMsg pv;
608
    int n, major, minor;
609
610
    if ((n = ReadExact(cl->sock, pv, sz_rfbProtocolVersionMsg)) <= 0) {
611
	if (n == 0)
612
	    rfbLog("rfbProcessClientProtocolVersion: client gone\n");
613
	else
614
	    rfbLogPerror("rfbProcessClientProtocolVersion: read");
615
	rfbCloseSock(cl->pScreen, cl->sock);
616
	return;
617
    }
618
619
    pv[sz_rfbProtocolVersionMsg] = 0;
620
    if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {
621
	rfbLog("rfbProcessClientProtocolVersion: not a valid RFB client\n");
622
	rfbCloseSock(cl->pScreen, cl->sock);
623
	return;
624
    }
625
    rfbLog("Using protocol version %d.%d\n", major, minor);
626
627
    if (major != rfbProtocolMajorVersion) {
628
	rfbLog("RFB protocol version mismatch - server %d.%d, client %d.%d\n",
629
		rfbProtocolMajorVersion,rfbProtocolMinorVersion,major,minor);
630
	rfbCloseSock(cl->pScreen, cl->sock);
631
	return;
632
    }
633
634
    /* Always use one of the two standard versions of the RFB protocol. */
635
    cl->protocol_minor_ver = minor;
636
    if (minor > rfbProtocolMinorVersion) {
637
	cl->protocol_minor_ver = rfbProtocolMinorVersion;
638
    } else if (minor < rfbProtocolMinorVersion) {
639
	cl->protocol_minor_ver = rfbProtocolFallbackMinorVersion;
640
    }
641
    if (minor != rfbProtocolMinorVersion &&
642
	minor != rfbProtocolFallbackMinorVersion) {
643
	rfbLog("Non-standard protocol version %d.%d, using %d.%d instead\n",
644
	       major, minor, rfbProtocolMajorVersion, cl->protocol_minor_ver);
645
    }
646
 
647
    /* TightVNC protocol extensions are not enabled yet. */
648
    cl->protocol_tightvnc = FALSE;
649
650
    rfbAuthNewClient(cl);
651
}
652
653
/*
654
 * rfbClientConnFailed is called when a client connection has failed
655
 * before the authentication stage.
656
 */
657
658
void
659
rfbClientConnFailed(cl, reason)
660
    rfbClientPtr cl;
661
    char *reason;
662
{
663
    int headerLen, reasonLen;
664
    char buf[8];
665
666
    headerLen = (cl->protocol_minor_ver >= 7) ? 1 : 4;
667
    reasonLen = strlen(reason);
668
    ((CARD32 *)buf)[0] = 0;
669
    ((CARD32 *)buf)[1] = Swap32IfLE(reasonLen);
670
671
    if ( WriteExact(cl->sock, buf, headerLen) < 0 ||
672
	 WriteExact(cl->sock, buf + 4, 4) < 0 ||
673
	 WriteExact(cl->sock, reason, reasonLen) < 0 ) {
674
	rfbLogPerror("rfbClientConnFailed: write");
675
    }
676
677
    rfbCloseSock(cl->pScreen, cl->sock);
678
}
679
680
681
/*
682
 * rfbProcessClientInitMessage is called when the client sends its
683
 * initialisation message.
684
 */
685
686
static void
687
rfbProcessClientInitMessage(cl)
688
    rfbClientPtr cl;
689
{
690
    VNCSCREENPTR(cl->pScreen);
691
    rfbClientInitMsg ci;
692
    char buf[256];
693
    rfbServerInitMsg *si = (rfbServerInitMsg *)buf;
694
    struct passwd *user;
695
    int len, n;
696
    rfbClientPtr otherCl, nextCl;
697
698
    if ((n = ReadExact(cl->sock, (char *)&ci,sz_rfbClientInitMsg)) <= 0) {
699
	if (n == 0)
700
	    rfbLog("rfbProcessClientInitMessage: client gone\n");
701
	else
702
	    rfbLogPerror("rfbProcessClientInitMessage: read");
703
	rfbCloseSock(cl->pScreen, cl->sock);
704
	return;
705
    }
706
707
    si->framebufferWidth = Swap16IfLE(pVNC->width);
708
    si->framebufferHeight = Swap16IfLE(pVNC->height);
709
    si->format = pVNC->rfbServerFormat;
710
    si->format.redMax = Swap16IfLE(si->format.redMax);
711
    si->format.greenMax = Swap16IfLE(si->format.greenMax);
712
    si->format.blueMax = Swap16IfLE(si->format.blueMax);
713
714
    user = getpwuid(getuid());
715
716
    if (strlen(desktopName) > 128)	/* sanity check on desktop name len */
717
	desktopName[128] = 0;
718
719
    if (user) {
720
	sprintf(buf + sz_rfbServerInitMsg, "%s's %s desktop (%s:%s)",
721
		user->pw_name, desktopName, rfbThisHost, display);
722
    } else {
723
	sprintf(buf + sz_rfbServerInitMsg, "%s desktop (%s:%s)",
724
		desktopName, rfbThisHost, display);
725
    }
726
    len = strlen(buf + sz_rfbServerInitMsg);
727
    si->nameLength = Swap32IfLE(len);
728
729
    if (WriteExact(cl->sock, buf, sz_rfbServerInitMsg + len) < 0) {
730
	rfbLogPerror("rfbProcessClientInitMessage: write");
731
	rfbCloseSock(cl->pScreen, cl->sock);
732
	return;
733
    }
734
735
    if (cl->protocol_tightvnc)
736
	rfbSendInteractionCaps(cl); /* protocol 3.7t */
737
738
    /* Dispatch client input to rfbProcessClientNormalMessage(). */
739
    cl->state = RFB_NORMAL;
740
741
    if (!cl->reverseConnection &&
742
	(pVNC->rfbNeverShared || (!pVNC->rfbAlwaysShared && !ci.shared))) {
743
744
	if (pVNC->rfbDontDisconnect) {
745
	    for (otherCl = rfbClientHead; otherCl; otherCl = otherCl->next) {
746
		if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) {
747
		    rfbLog("-dontdisconnect: Not shared & existing client\n");
748
		    rfbLog("  refusing new client %s\n", cl->host);
749
		    rfbCloseSock(cl->pScreen, cl->sock);
750
		    return;
751
		}
752
	    }
753
	} else {
754
	    for (otherCl = rfbClientHead; otherCl; otherCl = nextCl) {
755
		nextCl = otherCl->next;
756
		if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) {
757
		    rfbLog("Not shared - closing connection to client %s\n",
758
			   otherCl->host);
759
		    rfbCloseSock(otherCl->pScreen, otherCl->sock);
760
		}
761
	    }
762
	}
763
    }
764
}
765
766
767
/*
768
 * rfbSendInteractionCaps is called after sending the server
769
 * initialisation message, only if the protocol version is 3.130.
770
 * In this function, we send the lists of supported protocol messages
771
 * and encodings.
772
 */
773
774
/* Update these constants on changing capability lists below! */
775
#define N_SMSG_CAPS  0
776
#define N_CMSG_CAPS  0
777
#define N_ENC_CAPS  12
778
779
void
780
rfbSendInteractionCaps(cl)
781
    rfbClientPtr cl;
782
{
783
    rfbInteractionCapsMsg intr_caps;
784
    rfbCapabilityInfo enc_list[N_ENC_CAPS];
785
    int i;
786
787
    /* Fill in the header structure sent prior to capability lists. */
788
    intr_caps.nServerMessageTypes = Swap16IfLE(N_SMSG_CAPS);
789
    intr_caps.nClientMessageTypes = Swap16IfLE(N_CMSG_CAPS);
790
    intr_caps.nEncodingTypes = Swap16IfLE(N_ENC_CAPS);
791
    intr_caps.pad = 0;
792
793
    /* Supported server->client message types. */
794
    /* For future file transfer support:
795
    i = 0;
796
    SetCapInfo(&smsg_list[i++], rfbFileListData,           rfbTightVncVendor);
797
    SetCapInfo(&smsg_list[i++], rfbFileDownloadData,       rfbTightVncVendor);
798
    SetCapInfo(&smsg_list[i++], rfbFileUploadCancel,       rfbTightVncVendor);
799
    SetCapInfo(&smsg_list[i++], rfbFileDownloadFailed,     rfbTightVncVendor);
800
    if (i != N_SMSG_CAPS) {
801
	rfbLog("rfbSendInteractionCaps: assertion failed, i != N_SMSG_CAPS\n");
802
    	rfbCloseSock(cl->pScreen, cl->sock);
803
	return;
804
    }
805
    */
806
807
    /* Supported client->server message types. */
808
    /* For future file transfer support:
809
    i = 0;
810
    SetCapInfo(&cmsg_list[i++], rfbFileListRequest,        rfbTightVncVendor);
811
    SetCapInfo(&cmsg_list[i++], rfbFileDownloadRequest,    rfbTightVncVendor);
812
    SetCapInfo(&cmsg_list[i++], rfbFileUploadRequest,      rfbTightVncVendor);
813
    SetCapInfo(&cmsg_list[i++], rfbFileUploadData,         rfbTightVncVendor);
814
    SetCapInfo(&cmsg_list[i++], rfbFileDownloadCancel,     rfbTightVncVendor);
815
    SetCapInfo(&cmsg_list[i++], rfbFileUploadFailed,       rfbTightVncVendor);
816
    if (i != N_CMSG_CAPS) {
817
	rfbLog("rfbSendInteractionCaps: assertion failed, i != N_CMSG_CAPS\n");
818
    	rfbCloseSock(cl->pScreen, cl->sock);
819
	return;
820
    }
821
    */
822
823
    /* Encoding types. */
824
    i = 0;
825
    SetCapInfo(&enc_list[i++],  rfbEncodingCopyRect,       rfbStandardVendor);
826
    SetCapInfo(&enc_list[i++],  rfbEncodingRRE,            rfbStandardVendor);
827
    SetCapInfo(&enc_list[i++],  rfbEncodingCoRRE,          rfbStandardVendor);
828
    SetCapInfo(&enc_list[i++],  rfbEncodingHextile,        rfbStandardVendor);
829
    SetCapInfo(&enc_list[i++],  rfbEncodingZlib,           rfbTridiaVncVendor);
830
    SetCapInfo(&enc_list[i++],  rfbEncodingTight,          rfbTightVncVendor);
831
    SetCapInfo(&enc_list[i++],  rfbEncodingCompressLevel0, rfbTightVncVendor);
832
    SetCapInfo(&enc_list[i++],  rfbEncodingQualityLevel0,  rfbTightVncVendor);
833
    SetCapInfo(&enc_list[i++],  rfbEncodingXCursor,        rfbTightVncVendor);
834
    SetCapInfo(&enc_list[i++],  rfbEncodingRichCursor,     rfbTightVncVendor);
835
    SetCapInfo(&enc_list[i++],  rfbEncodingPointerPos,     rfbTightVncVendor);
836
    SetCapInfo(&enc_list[i++],  rfbEncodingLastRect,       rfbTightVncVendor);
837
    if (i != N_ENC_CAPS) {
838
	rfbLog("rfbSendInteractionCaps: assertion failed, i != N_ENC_CAPS\n");
839
    	rfbCloseSock(cl->pScreen, cl->sock);
840
	return;
841
    }
842
843
    /* Send header and capability lists */
844
    if (WriteExact(cl->sock, (char *)&intr_caps,
845
		   sz_rfbInteractionCapsMsg) < 0 ||
846
	WriteExact(cl->sock, (char *)&enc_list[0],
847
		   sz_rfbCapabilityInfo * N_ENC_CAPS) < 0) {
848
	rfbLogPerror("rfbSendInteractionCaps: write");
849
    	rfbCloseSock(cl->pScreen, cl->sock);
850
	return;
851
    }
852
853
    /* Dispatch client input to rfbProcessClientNormalMessage(). */
854
    cl->state = RFB_NORMAL;
855
}
856
857
858
/*
859
 * rfbProcessClientNormalMessage is called when the client has sent a normal
860
 * protocol message.
861
 */
862
863
static void
864
rfbProcessClientNormalMessage(cl)
865
    rfbClientPtr cl;
866
{
867
    VNCSCREENPTR(cl->pScreen);
868
    int n;
869
    rfbClientToServerMsg msg;
870
    char *str;
871
872
    if (pVNC->rfbUserAccept) {
873
	/* 
874
	 * We've asked for another level of user authentication
875
	 * If the user has not validated this connected, don't
876
	 * process it.
877
	 */
878
	/*
879
 	 * NOTE: we do it here, so the vncviewer knows it's
880
	 * connected, but waiting for the first screen update
881
	 */
882
	if (cl->userAccepted == VNC_USER_UNDEFINED) {
883
	    usleep(10);
884
	    return;
885
	}
886
	if (cl->userAccepted == VNC_USER_DISCONNECT) {
887
	    rfbCloseSock(cl->pScreen, cl->sock);
888
	    return;
889
	}
890
    }
891
892
    if ((n = ReadExact(cl->sock, (char *)&msg, 1)) <= 0) {
893
	if (n != 0)
894
	    rfbLogPerror("rfbProcessClientNormalMessage: read");
895
	rfbCloseSock(cl->pScreen, cl->sock);
896
	return;
897
    }
898
899
    switch (msg.type) {
900
901
    case rfbSetPixelFormat:
902
903
	if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
904
			   sz_rfbSetPixelFormatMsg - 1)) <= 0) {
905
	    if (n != 0)
906
		rfbLogPerror("rfbProcessClientNormalMessage: read");
907
	    rfbCloseSock(cl->pScreen, cl->sock);
908
	    return;
909
	}
910
911
	cl->format.bitsPerPixel = msg.spf.format.bitsPerPixel;
912
	cl->format.depth = msg.spf.format.depth;
913
	cl->format.bigEndian = (msg.spf.format.bigEndian ? 1 : 0);
914
	cl->format.trueColour = (msg.spf.format.trueColour ? 1 : 0);
915
	cl->format.redMax = Swap16IfLE(msg.spf.format.redMax);
916
	cl->format.greenMax = Swap16IfLE(msg.spf.format.greenMax);
917
	cl->format.blueMax = Swap16IfLE(msg.spf.format.blueMax);
918
	cl->format.redShift = msg.spf.format.redShift;
919
	cl->format.greenShift = msg.spf.format.greenShift;
920
	cl->format.blueShift = msg.spf.format.blueShift;
921
922
	cl->readyForSetColourMapEntries = TRUE;
923
924
	rfbSetTranslateFunction(cl);
925
	return;
926
927
928
    case rfbFixColourMapEntries:
929
	if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
930
			   sz_rfbFixColourMapEntriesMsg - 1)) <= 0) {
931
	    if (n != 0)
932
		rfbLogPerror("rfbProcessClientNormalMessage: read");
933
	    rfbCloseSock(cl->pScreen, cl->sock);
934
	    return;
935
	}
936
	rfbLog("rfbProcessClientNormalMessage: %s",
937
		"FixColourMapEntries unsupported\n");
938
	rfbCloseSock(cl->pScreen, cl->sock);
939
	return;
940
941
942
    case rfbSetEncodings:
943
    {
944
	int i;
945
	CARD32 enc;
946
947
	if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
948
			   sz_rfbSetEncodingsMsg - 1)) <= 0) {
949
	    if (n != 0)
950
		rfbLogPerror("rfbProcessClientNormalMessage: read");
951
	    rfbCloseSock(cl->pScreen, cl->sock);
952
	    return;
953
	}
954
955
	msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings);
956
957
	cl->preferredEncoding = -1;
958
	cl->useCopyRect = FALSE;
959
	cl->enableCursorShapeUpdates = FALSE;
960
	cl->enableCursorPosUpdates = FALSE;
961
	cl->enableLastRectEncoding = FALSE;
962
#ifdef CHROMIUM
963
	cl->enableChromiumEncoding = FALSE;
964
#endif
965
	cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION;
966
	cl->tightQualityLevel = -1;
967
968
	for (i = 0; i < msg.se.nEncodings; i++) {
969
	    if ((n = ReadExact(cl->sock, (char *)&enc, 4)) <= 0) {
970
		if (n != 0)
971
		    rfbLogPerror("rfbProcessClientNormalMessage: read");
972
		rfbCloseSock(cl->pScreen, cl->sock);
973
		return;
974
	    }
975
	    enc = Swap32IfLE(enc);
976
977
	    switch (enc) {
978
979
	    case rfbEncodingCopyRect:
980
		cl->useCopyRect = TRUE;
981
		rfbLog("Using copyrect encoding for client %s\n",
982
			   cl->host);
983
		break;
984
	    case rfbEncodingRaw:
985
		if (cl->preferredEncoding == -1) {
986
		    cl->preferredEncoding = enc;
987
		    rfbLog("Using raw encoding for client %s\n",
988
			   cl->host);
989
		}
990
		break;
991
	    case rfbEncodingRRE:
992
		if (cl->preferredEncoding == -1) {
993
		    cl->preferredEncoding = enc;
994
		    rfbLog("Using rre encoding for client %s\n",
995
			   cl->host);
996
		}
997
		break;
998
	    case rfbEncodingCoRRE:
999
		if (cl->preferredEncoding == -1) {
1000
		    cl->preferredEncoding = enc;
1001
		    rfbLog("Using CoRRE encoding for client %s\n",
1002
			   cl->host);
1003
		}
1004
		break;
1005
	    case rfbEncodingHextile:
1006
		if (cl->preferredEncoding == -1) {
1007
		    cl->preferredEncoding = enc;
1008
		    rfbLog("Using hextile encoding for client %s\n",
1009
			   cl->host);
1010
		}
1011
		break;
1012
	    case rfbEncodingZlib:
1013
		if (cl->preferredEncoding == -1) {
1014
		    cl->preferredEncoding = enc;
1015
		    rfbLog("Using zlib encoding for client %s\n",
1016
			   cl->host);
1017
		}
1018
              break;
1019
	    case rfbEncodingTight:
1020
		if (cl->preferredEncoding == -1) {
1021
		    cl->preferredEncoding = enc;
1022
		    rfbLog("Using tight encoding for client %s\n",
1023
			   cl->host);
1024
		}
1025
		break;
1026
	    case rfbEncodingXCursor:
1027
		rfbLog("Enabling X-style cursor updates for client %s\n",
1028
		       cl->host);
1029
		cl->enableCursorShapeUpdates = TRUE;
1030
		cl->useRichCursorEncoding = FALSE;
1031
		cl->cursorWasChanged = TRUE;
1032
		break;
1033
	    case rfbEncodingRichCursor:
1034
		if (!cl->enableCursorShapeUpdates) {
1035
		    rfbLog("Enabling full-color cursor updates for client "
1036
			   "%s\n", cl->host);
1037
		    cl->enableCursorShapeUpdates = TRUE;
1038
		    cl->useRichCursorEncoding = TRUE;
1039
		    cl->cursorWasChanged = TRUE;
1040
		}
1041
		break;
1042
	    case rfbEncodingPointerPos:
1043
		if (!cl->enableCursorPosUpdates) {
1044
		    rfbLog("Enabling cursor position updates for client %s\n",
1045
			   cl->host);
1046
		    cl->enableCursorPosUpdates = TRUE;
1047
		    cl->cursorWasMoved = TRUE;
1048
		    cl->cursorX = -1;
1049
		    cl->cursorY = -1;
1050
		}
1051
	        break;
1052
	    case rfbEncodingLastRect:
1053
		if (!cl->enableLastRectEncoding) {
1054
		    rfbLog("Enabling LastRect protocol extension for client "
1055
			   "%s\n", cl->host);
1056
		    cl->enableLastRectEncoding = TRUE;
1057
		}
1058
		break;
1059
#ifdef CHROMIUM
1060
	    case rfbEncodingChromium:
1061
	    case rfbEncodingChromium2:
1062
		if (!cl->enableChromiumEncoding) {
1063
		    cl->enableChromiumEncoding = TRUE;
1064
		    /* This tells OpenGL apps/replicate SPUs that new viewer
1065
                     * has attached.
1066
                     */
1067
    		    GenerateVncChromiumConnectedEvent(cl->sock);
1068
                    if (enc == rfbEncodingChromium) {
1069
                        /* Generate exposures for all windows */
1070
                        WindowPtr pWin = WindowTable[cl->pScreen->myNum];
1071
                        rfbSetClip(pWin, 1);
1072
                    }
1073
                    else {
1074
                        /* don't generate exposures for Chromium2 because
1075
                         * that confused DMX.
1076
                         */
1077
                    }
1078
		}
1079
		break;
1080
#endif
1081
	    default:
1082
		if ( enc >= (CARD32)rfbEncodingCompressLevel0 &&
1083
		     enc <= (CARD32)rfbEncodingCompressLevel9 ) {
1084
		    cl->zlibCompressLevel = enc & 0x0F;
1085
		    cl->tightCompressLevel = enc & 0x0F;
1086
		    rfbLog("Using compression level %d for client %s\n",
1087
			   cl->tightCompressLevel, cl->host);
1088
		} else if ( enc >= (CARD32)rfbEncodingQualityLevel0 &&
1089
			    enc <= (CARD32)rfbEncodingQualityLevel9 ) {
1090
		    cl->tightQualityLevel = enc & 0x0F;
1091
		    rfbLog("Using image quality level %d for client %s\n",
1092
			   cl->tightQualityLevel, cl->host);
1093
		} else {
1094
		    rfbLog("rfbProcessClientNormalMessage: ignoring unknown "
1095
			   "encoding %d\n", (int)enc);
1096
		}
1097
	    }
1098
	}
1099
1100
	if (cl->preferredEncoding == -1) {
1101
	    cl->preferredEncoding = rfbEncodingRaw;
1102
 	    rfbLog("No encoding specified - using raw encoding for client %s\n",
1103
			   cl->host);
1104
	}
1105
1106
	if (cl->enableCursorPosUpdates && !cl->enableCursorShapeUpdates) {
1107
	    rfbLog("Disabling cursor position updates for client %s\n",
1108
		   cl->host);
1109
	    cl->enableCursorPosUpdates = FALSE;
1110
	}
1111
1112
#if XFREE86VNC
1113
	/*
1114
	 * With XFree86 and the hardware cursor's we need to put up the
1115
	 * cursor again, and if we've detected a cursor shapeless client
1116
	 * we need to disable hardware cursors.
1117
	 */
1118
	if (!cl->enableCursorShapeUpdates)
1119
	    pVNC->SWCursor = (Bool *)TRUE;
1120
	else
1121
	    pVNC->SWCursor = (Bool *)FALSE;
1122
1123
	{
1124
		int x, y;
1125
		miPointerPosition(&x, &y); /*XXX deprecated*/
1126
		(*pVNC->spriteFuncs->SetCursor)(cl->pScreen, pVNC->pCurs, x, y);
1127
	}
1128
#endif
1129
1130
	return;
1131
    }
1132
1133
1134
    case rfbFramebufferUpdateRequest:
1135
    {
1136
	RegionRec tmpRegion;
1137
	BoxRec box;
1138
1139
#ifdef CORBA
1140
	addCapability(cl, DISPLAY_DEVICE);
1141
#endif
1142
1143
	if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
1144
			   sz_rfbFramebufferUpdateRequestMsg-1)) <= 0) {
1145
	    if (n != 0)
1146
		rfbLogPerror("rfbProcessClientNormalMessage: read");
1147
	    rfbCloseSock(cl->pScreen, cl->sock);
1148
	    return;
1149
	}
1150
1151
	box.x1 = Swap16IfLE(msg.fur.x);
1152
	box.y1 = Swap16IfLE(msg.fur.y);
1153
	box.x2 = box.x1 + Swap16IfLE(msg.fur.w);
1154
	box.y2 = box.y1 + Swap16IfLE(msg.fur.h);
1155
	SAFE_REGION_INIT(cl->pScreen,&tmpRegion,&box,0);
1156
1157
	REGION_UNION(cl->pScreen, &cl->requestedRegion, &cl->requestedRegion,
1158
		     &tmpRegion);
1159
1160
	if (!cl->readyForSetColourMapEntries) {
1161
	    /* client hasn't sent a SetPixelFormat so is using server's */
1162
	    cl->readyForSetColourMapEntries = TRUE;
1163
	    if (!cl->format.trueColour) {
1164
		if (!rfbSetClientColourMap(cl, 0, 0)) {
1165
		    REGION_UNINIT(cl->pScreen,&tmpRegion);
1166
		    return;
1167
		}
1168
	    }
1169
	}
1170
1171
	if (!msg.fur.incremental) {
1172
	    REGION_UNION(cl->pScreen,&cl->modifiedRegion,&cl->modifiedRegion,
1173
			 &tmpRegion);
1174
	    REGION_SUBTRACT(cl->pScreen,&cl->copyRegion,&cl->copyRegion,
1175
			    &tmpRegion);
1176
	}
1177
1178
#ifndef DMXVNC
1179
        /* don't try to send any pixel data - we'll crash */
1180
	if (FB_UPDATE_PENDING(cl)) {
1181
	    rfbSendFramebufferUpdate(cl->pScreen, cl);
1182
	}
1183
#endif
1184
1185
	REGION_UNINIT(cl->pScreen,&tmpRegion);
1186
	return;
1187
    }
1188
1189
    case rfbKeyEvent:
1190
1191
	cl->rfbKeyEventsRcvd++;
1192
1193
	if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
1194
			   sz_rfbKeyEventMsg - 1)) <= 0) {
1195
	    if (n != 0)
1196
		rfbLogPerror("rfbProcessClientNormalMessage: read");
1197
	    rfbCloseSock(cl->pScreen, cl->sock);
1198
	    return;
1199
	}
1200
1201
#ifdef CORBA
1202
	addCapability(cl, KEYBOARD_DEVICE);
1203
1204
	if (!isKeyboardEnabled(cl))
1205
	    return;
1206
#endif
1207
        /*ErrorF("Key event: %d\n", msg.ke.key);*/
1208
	if (!pVNC->rfbViewOnly && !cl->viewOnly) {
1209
	    KbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), cl);
1210
	}
1211
	return;
1212
1213
1214
    case rfbPointerEvent:
1215
1216
	cl->rfbPointerEventsRcvd++;
1217
1218
	if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
1219
			   sz_rfbPointerEventMsg - 1)) <= 0) {
1220
	    if (n != 0)
1221
		rfbLogPerror("rfbProcessClientNormalMessage: read");
1222
	    rfbCloseSock(cl->pScreen, cl->sock);
1223
	    return;
1224
	}
1225
1226
#ifdef CORBA
1227
	addCapability(cl, POINTER_DEVICE);
1228
1229
	if (!isPointerEnabled(cl))
1230
	    return;
1231
#endif
1232
1233
	if (pointerClient && (pointerClient != cl))
1234
	    return;
1235
1236
	if (msg.pe.buttonMask == 0)
1237
	    pointerClient = NULL;
1238
	else
1239
	    pointerClient = cl;
1240
1241
	if (!pVNC->rfbViewOnly && !cl->viewOnly) {
1242
	    cl->cursorX = (int)Swap16IfLE(msg.pe.x);
1243
            cl->cursorY = (int)Swap16IfLE(msg.pe.y);
1244
	    PtrAddEvent(msg.pe.buttonMask, cl->cursorX, cl->cursorY, cl);
1245
	}
1246
	return;
1247
1248
1249
    case rfbClientCutText:
1250
1251
	if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
1252
			   sz_rfbClientCutTextMsg - 1)) <= 0) {
1253
	    if (n != 0)
1254
		rfbLogPerror("rfbProcessClientNormalMessage: read");
1255
	    rfbCloseSock(cl->pScreen, cl->sock);
1256
	    return;
1257
	}
1258
1259
	msg.cct.length = Swap32IfLE(msg.cct.length);
1260
1261
	str = (char *)xalloc(msg.cct.length);
1262
1263
	if ((n = ReadExact(cl->sock, str, msg.cct.length)) <= 0) {
1264
	    if (n != 0)
1265
		rfbLogPerror("rfbProcessClientNormalMessage: read");
1266
	    xfree(str);
1267
	    rfbCloseSock(cl->pScreen, cl->sock);
1268
	    return;
1269
	}
1270
1271
	/* NOTE: We do not accept cut text from a view-only client */
1272
	if (!cl->viewOnly)
1273
	    rfbSetXCutText(str, msg.cct.length);
1274
1275
	xfree(str);
1276
	return;
1277
1278
#ifdef CHROMIUM
1279
    case rfbChromiumStop:
1280
	if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
1281
			   sz_rfbChromiumStopMsg - 1)) <= 0) {
1282
	    if (n != 0)
1283
		rfbLogPerror("rfbProcessClientNormalMessage: read");
1284
	    rfbCloseSock(cl->pScreen, cl->sock);
1285
	    return;
1286
	}
1287
1288
	/* would we use msg.csd.port ??? */
1289
1290
	cl->chromium_port = 0;
1291
1292
	/* tear down window information */
1293
    	{
1294
	    CRWindowTable *wt, *nextWt = NULL;
1295
1296
   	    for (wt = windowTable; wt; wt = nextWt) {
1297
   	 	nextWt = wt->next;
1298
		xfree(wt);
1299
	    }
1300
1301
	    windowTable = NULL;
1302
	}
1303
1304
	return;
1305
1306
    case rfbChromiumExpose:
1307
	if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
1308
			   sz_rfbChromiumExposeMsg - 1)) <= 0) {
1309
	    if (n != 0)
1310
		rfbLogPerror("rfbProcessClientNormalMessage: read");
1311
	    rfbCloseSock(cl->pScreen, cl->sock);
1312
	    return;
1313
	}
1314
1315
	/* find the window and re-expose it */
1316
    	{
1317
	    CRWindowTable *wt, *nextWt = NULL;
1318
1319
   	    for (wt = windowTable; wt; wt = nextWt) {
1320
   	 	nextWt = wt->next;
1321
		if (wt->CRwinId == msg.cse.winid) {
1322
			WindowPtr pWin;
1323
	    		pWin = LookupIDByType(wt->XwinId, RT_WINDOW);
1324
			if (pWin) {
1325
				miSendExposures(pWin, &pWin->clipList,
1326
						pWin->drawable.x,
1327
						pWin->drawable.y);
1328
				FlushAllOutput();
1329
			}
1330
		}
1331
	    }
1332
	}
1333
1334
	return;
1335
#endif
1336
1337
    default:
1338
1339
	rfbLog("rfbProcessClientNormalMessage: unknown message type %d\n",
1340
		msg.type);
1341
	rfbLog(" ... closing connection\n");
1342
	rfbCloseSock(cl->pScreen, cl->sock);
1343
	return;
1344
    }
1345
}
1346
1347
1348
1349
/*
1350
 * rfbSendFramebufferUpdate - send the currently pending framebuffer update to
1351
 * the RFB client.
1352
 */
1353
1354
Bool
1355
rfbSendFramebufferUpdate(pScreen, cl)
1356
    ScreenPtr pScreen;
1357
    rfbClientPtr cl;
1358
{
1359
    VNCSCREENPTR(pScreen);
1360
    int i;
1361
    int nUpdateRegionRects;
1362
    rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)pVNC->updateBuf;
1363
    RegionRec updateRegion, updateCopyRegion;
1364
    int dx, dy;
1365
    Bool sendCursorShape = FALSE;
1366
    Bool sendCursorPos = FALSE;
1367
1368
    /*
1369
     * If this client understands cursor shape updates, cursor should be
1370
     * removed from the framebuffer. Otherwise, make sure it's put up.
1371
     */
1372
1373
#if !XFREE86VNC
1374
    if (cl->enableCursorShapeUpdates) {
1375
	if (pVNC->cursorIsDrawn)
1376
	    rfbSpriteRemoveCursor(pScreen);
1377
	if (!pVNC->cursorIsDrawn && cl->cursorWasChanged)
1378
	    sendCursorShape = TRUE;
1379
    } else {
1380
	if (!pVNC->cursorIsDrawn)
1381
	    rfbSpriteRestoreCursor(pScreen);
1382
    }
1383
#else
1384
    if (cl->enableCursorShapeUpdates)
1385
	if (cl->cursorWasChanged) 
1386
	    sendCursorShape = TRUE;
1387
#endif
1388
1389
    /*
1390
     * Do we plan to send cursor position update?
1391
     */
1392
1393
    if (cl->enableCursorPosUpdates && cl->cursorWasMoved)
1394
	sendCursorPos = TRUE;
1395
1396
    /*
1397
     * The modifiedRegion may overlap the destination copyRegion.  We remove
1398
     * any overlapping bits from the copyRegion (since they'd only be
1399
     * overwritten anyway).
1400
     */
1401
1402
    REGION_SUBTRACT(pScreen, &cl->copyRegion, &cl->copyRegion,
1403
		    &cl->modifiedRegion);
1404
1405
    /*
1406
     * The client is interested in the region requestedRegion.  The region
1407
     * which should be updated now is the intersection of requestedRegion
1408
     * and the union of modifiedRegion and copyRegion.  If it's empty then
1409
     * no update is needed.
1410
     */
1411
1412
    REGION_NULL(pScreen,&updateRegion);
1413
    REGION_UNION(pScreen, &updateRegion, &cl->copyRegion,
1414
		 &cl->modifiedRegion);
1415
    REGION_INTERSECT(pScreen, &updateRegion, &cl->requestedRegion,
1416
		     &updateRegion);
1417
1418
    if ( !REGION_NOTEMPTY(pScreen,&updateRegion) &&
1419
	 !sendCursorShape && !sendCursorPos ) {
1420
	REGION_UNINIT(pScreen,&updateRegion);
1421
	return TRUE;
1422
    }
1423
1424
    /*
1425
     * We assume that the client doesn't have any pixel data outside the
1426
     * requestedRegion.  In other words, both the source and destination of a
1427
     * copy must lie within requestedRegion.  So the region we can send as a
1428
     * copy is the intersection of the copyRegion with both the requestedRegion
1429
     * and the requestedRegion translated by the amount of the copy.  We set
1430
     * updateCopyRegion to this.
1431
     */
1432
1433
    REGION_NULL(pScreen,&updateCopyRegion);
1434
    REGION_INTERSECT(pScreen, &updateCopyRegion, &cl->copyRegion,
1435
		     &cl->requestedRegion);
1436
    REGION_TRANSLATE(pScreen, &cl->requestedRegion, cl->copyDX, cl->copyDY);
1437
    REGION_INTERSECT(pScreen, &updateCopyRegion, &updateCopyRegion,
1438
		     &cl->requestedRegion);
1439
    dx = cl->copyDX;
1440
    dy = cl->copyDY;
1441
1442
    /*
1443
     * Next we remove updateCopyRegion from updateRegion so that updateRegion
1444
     * is the part of this update which is sent as ordinary pixel data (i.e not
1445
     * a copy).
1446
     */
1447
1448
    REGION_SUBTRACT(pScreen, &updateRegion, &updateRegion, &updateCopyRegion);
1449
1450
    /*
1451
     * Finally we leave modifiedRegion to be the remainder (if any) of parts of
1452
     * the screen which are modified but outside the requestedRegion.  We also
1453
     * empty both the requestedRegion and the copyRegion - note that we never
1454
     * carry over a copyRegion for a future update.
1455
     */
1456
1457
    REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
1458
		 &cl->copyRegion);
1459
    REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
1460
		    &updateRegion);
1461
    REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
1462
		    &updateCopyRegion);
1463
1464
    REGION_EMPTY(pScreen, &cl->requestedRegion);
1465
    REGION_EMPTY(pScreen, &cl->copyRegion);
1466
    cl->copyDX = 0;
1467
    cl->copyDY = 0;
1468
1469
    /*
1470
     * Now send the update.
1471
     */
1472
1473
    cl->rfbFramebufferUpdateMessagesSent++;
1474
1475
    if (cl->preferredEncoding == rfbEncodingCoRRE) {
1476
	nUpdateRegionRects = 0;
1477
1478
	for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) {
1479
	    int x = REGION_RECTS(&updateRegion)[i].x1;
1480
	    int y = REGION_RECTS(&updateRegion)[i].y1;
1481
	    int w = REGION_RECTS(&updateRegion)[i].x2 - x;
1482
	    int h = REGION_RECTS(&updateRegion)[i].y2 - y;
1483
	    nUpdateRegionRects += (((w-1) / cl->correMaxWidth + 1)
1484
				     * ((h-1) / cl->correMaxHeight + 1));
1485
	}
1486
    } else if (cl->preferredEncoding == rfbEncodingZlib) {
1487
	nUpdateRegionRects = 0;
1488
1489
	for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) {
1490
	    int x = REGION_RECTS(&updateRegion)[i].x1;
1491
	    int y = REGION_RECTS(&updateRegion)[i].y1;
1492
	    int w = REGION_RECTS(&updateRegion)[i].x2 - x;
1493
	    int h = REGION_RECTS(&updateRegion)[i].y2 - y;
1494
	    nUpdateRegionRects += (((h-1) / (ZLIB_MAX_SIZE( w ) / w)) + 1);
1495
	}
1496
    } else if (cl->preferredEncoding == rfbEncodingTight) {
1497
	nUpdateRegionRects = 0;
1498
1499
	for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) {
1500
	    int x = REGION_RECTS(&updateRegion)[i].x1;
1501
	    int y = REGION_RECTS(&updateRegion)[i].y1;
1502
	    int w = REGION_RECTS(&updateRegion)[i].x2 - x;
1503
	    int h = REGION_RECTS(&updateRegion)[i].y2 - y;
1504
	    int n = rfbNumCodedRectsTight(cl, x, y, w, h);
1505
	    if (n == 0) {
1506
		nUpdateRegionRects = 0xFFFF;
1507
		break;
1508
	    }
1509
	    nUpdateRegionRects += n;
1510
	}
1511
    } else {
1512
	nUpdateRegionRects = REGION_NUM_RECTS(&updateRegion);
1513
    }
1514
1515
    fu->type = rfbFramebufferUpdate;
1516
    if (nUpdateRegionRects != 0xFFFF) {
1517
	fu->nRects = Swap16IfLE(REGION_NUM_RECTS(&updateCopyRegion) +
1518
				nUpdateRegionRects +
1519
				!!sendCursorShape + !!sendCursorPos);
1520
    } else {
1521
	fu->nRects = 0xFFFF;
1522
    }
1523
    pVNC->ublen = sz_rfbFramebufferUpdateMsg;
1524
1525
    if (sendCursorShape) {
1526
	cl->cursorWasChanged = FALSE;
1527
	if (!rfbSendCursorShape(cl, pScreen))
1528
	    return FALSE;
1529
    }
1530
1531
    if (sendCursorPos) {
1532
	cl->cursorWasMoved = FALSE;
1533
	if (!rfbSendCursorPos(cl, pScreen))
1534
 	    return FALSE;
1535
    }
1536
1537
    if (REGION_NOTEMPTY(pScreen,&updateCopyRegion)) {
1538
	if (!rfbSendCopyRegion(cl,&updateCopyRegion,dx,dy)) {
1539
	    REGION_UNINIT(pScreen,&updateRegion);
1540
	    REGION_UNINIT(pScreen,&updateCopyRegion);
1541
	    return FALSE;
1542
	}
1543
    }
1544
1545
    REGION_UNINIT(pScreen,&updateCopyRegion);
1546
1547
    for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) {
1548
	int x = REGION_RECTS(&updateRegion)[i].x1;
1549
	int y = REGION_RECTS(&updateRegion)[i].y1;
1550
	int w = REGION_RECTS(&updateRegion)[i].x2 - x;
1551
	int h = REGION_RECTS(&updateRegion)[i].y2 - y;
1552
1553
	cl->rfbRawBytesEquivalent += (sz_rfbFramebufferUpdateRectHeader
1554
				      + w * (cl->format.bitsPerPixel / 8) * h);
1555
1556
	switch (cl->preferredEncoding) {
1557
	case rfbEncodingRaw:
1558
	    if (!rfbSendRectEncodingRaw(cl, x, y, w, h)) {
1559
		REGION_UNINIT(pScreen,&updateRegion);
1560
		return FALSE;
1561
	    }
1562
	    break;
1563
	case rfbEncodingRRE:
1564
	    if (!rfbSendRectEncodingRRE(cl, x, y, w, h)) {
1565
		REGION_UNINIT(pScreen,&updateRegion);
1566
		return FALSE;
1567
	    }
1568
	    break;
1569
	case rfbEncodingCoRRE:
1570
	    if (!rfbSendRectEncodingCoRRE(cl, x, y, w, h)) {
1571
		REGION_UNINIT(pScreen,&updateRegion);
1572
		return FALSE;
1573
	    }
1574
	    break;
1575
	case rfbEncodingHextile:
1576
	    if (!rfbSendRectEncodingHextile(cl, x, y, w, h)) {
1577
		REGION_UNINIT(pScreen,&updateRegion);
1578
		return FALSE;
1579
	    }
1580
	    break;
1581
	case rfbEncodingZlib:
1582
	    if (!rfbSendRectEncodingZlib(cl, x, y, w, h)) {
1583
		REGION_UNINIT(pScreen,&updateRegion);
1584
		return FALSE;
1585
	    }
1586
	    break;
1587
	case rfbEncodingTight:
1588
	    if (!rfbSendRectEncodingTight(cl, x, y, w, h)) {
1589
		REGION_UNINIT(pScreen,&updateRegion);
1590
		return FALSE;
1591
	    }
1592
	    break;
1593
	}
1594
    }
1595
1596
    REGION_UNINIT(pScreen,&updateRegion);
1597
1598
    if (nUpdateRegionRects == 0xFFFF && !rfbSendLastRectMarker(cl))
1599
	return FALSE;
1600
1601
    if (!rfbSendUpdateBuf(cl))
1602
	return FALSE;
1603
1604
    return TRUE;
1605
}
1606
1607
1608
1609
/*
1610
 * Send the copy region as a string of CopyRect encoded rectangles.
1611
 * The only slightly tricky thing is that we should send the messages in
1612
 * the correct order so that an earlier CopyRect will not corrupt the source
1613
 * of a later one.
1614
 */
1615
1616
static Bool
1617
rfbSendCopyRegion(cl, reg, dx, dy)
1618
    rfbClientPtr cl;
1619
    RegionPtr reg;
1620
    int dx, dy;
1621
{
1622
    VNCSCREENPTR(cl->pScreen);
1623
    int nrects, nrectsInBand, x_inc, y_inc, thisRect, firstInNextBand;
1624
    int x, y, w, h;
1625
    rfbFramebufferUpdateRectHeader rect;
1626
    rfbCopyRect cr;
1627
1628
    nrects = REGION_NUM_RECTS(reg);
1629
1630
    if (dx <= 0) {
1631
	x_inc = 1;
1632
    } else {
1633
	x_inc = -1;
1634
    }
1635
1636
    if (dy <= 0) {
1637
	thisRect = 0;
1638
	y_inc = 1;
1639
    } else {
1640
	thisRect = nrects - 1;
1641
	y_inc = -1;
1642
    }
1643
1644
    while (nrects > 0) {
1645
1646
	firstInNextBand = thisRect;
1647
	nrectsInBand = 0;
1648
1649
	while ((nrects > 0) &&
1650
	       (REGION_RECTS(reg)[firstInNextBand].y1
1651
		== REGION_RECTS(reg)[thisRect].y1))
1652
	{
1653
	    firstInNextBand += y_inc;
1654
	    nrects--;
1655
	    nrectsInBand++;
1656
	}
1657
1658
	if (x_inc != y_inc) {
1659
	    thisRect = firstInNextBand - y_inc;
1660
	}
1661
1662
	while (nrectsInBand > 0) {
1663
	    if ((pVNC->ublen + sz_rfbFramebufferUpdateRectHeader
1664
		 + sz_rfbCopyRect) > UPDATE_BUF_SIZE)
1665
	    {
1666
		if (!rfbSendUpdateBuf(cl))
1667
		    return FALSE;
1668
	    }
1669
1670
	    x = REGION_RECTS(reg)[thisRect].x1;
1671
	    y = REGION_RECTS(reg)[thisRect].y1;
1672
	    w = REGION_RECTS(reg)[thisRect].x2 - x;
1673
	    h = REGION_RECTS(reg)[thisRect].y2 - y;
1674
1675
	    rect.r.x = Swap16IfLE(x);
1676
	    rect.r.y = Swap16IfLE(y);
1677
	    rect.r.w = Swap16IfLE(w);
1678
	    rect.r.h = Swap16IfLE(h);
1679
	    rect.encoding = Swap32IfLE(rfbEncodingCopyRect);
1680
1681
	    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,
1682
		   sz_rfbFramebufferUpdateRectHeader);
1683
	    pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
1684
1685
	    cr.srcX = Swap16IfLE(x - dx);
1686
	    cr.srcY = Swap16IfLE(y - dy);
1687
1688
	    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&cr, sz_rfbCopyRect);
1689
	    pVNC->ublen += sz_rfbCopyRect;
1690
1691
	    cl->rfbRectanglesSent[rfbEncodingCopyRect]++;
1692
	    cl->rfbBytesSent[rfbEncodingCopyRect]
1693
		+= sz_rfbFramebufferUpdateRectHeader + sz_rfbCopyRect;
1694
1695
	    thisRect += x_inc;
1696
	    nrectsInBand--;
1697
	}
1698
1699
	thisRect = firstInNextBand;
1700
    }
1701
1702
    return TRUE;
1703
}
1704
1705
1706
/*
1707
 * Send a given rectangle in raw encoding (rfbEncodingRaw).
1708
 */
1709
1710
Bool
1711
rfbSendRectEncodingRaw(cl, x, y, w, h)
1712
    rfbClientPtr cl;
1713
    int x, y, w, h;
1714
{
1715
    VNCSCREENPTR(cl->pScreen);
1716
    rfbFramebufferUpdateRectHeader rect;
1717
    int nlines;
1718
    int bytesPerLine = w * (cl->format.bitsPerPixel / 8);
1719
    int newy = y;
1720
1721
    /* Flush the buffer to guarantee correct alignment for translateFn(). */
1722
    if (pVNC->ublen > 0) {
1723
	if (!rfbSendUpdateBuf(cl))
1724
	    return FALSE;
1725
    }
1726
1727
    rect.r.x = Swap16IfLE(x);
1728
    rect.r.y = Swap16IfLE(y);
1729
    rect.r.w = Swap16IfLE(w);
1730
    rect.r.h = Swap16IfLE(h);
1731
    rect.encoding = Swap32IfLE(rfbEncodingRaw);
1732
1733
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader);
1734
    pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
1735
1736
    cl->rfbRectanglesSent[rfbEncodingRaw]++;
1737
    cl->rfbBytesSent[rfbEncodingRaw]
1738
	+= sz_rfbFramebufferUpdateRectHeader + bytesPerLine * h;
1739
1740
    nlines = (UPDATE_BUF_SIZE - pVNC->ublen) / bytesPerLine;
1741
1742
    while (TRUE) {
1743
	if (nlines > h)
1744
	    nlines = h;
1745
1746
	(*cl->translateFn)(cl->pScreen, cl->translateLookupTable, &pVNC->rfbServerFormat,
1747
			   &cl->format, &pVNC->updateBuf[pVNC->ublen],
1748
			   pVNC->paddedWidthInBytes, w, nlines, x, newy);
1749
1750
	pVNC->ublen += nlines * bytesPerLine;
1751
	h -= nlines;
1752
	newy += nlines;
1753
1754
	if (h == 0)	/* rect fitted in buffer, do next one */
1755
	    return TRUE;
1756
1757
	/* buffer full - flush partial rect and do another nlines */
1758
1759
	if (!rfbSendUpdateBuf(cl))
1760
	    return FALSE;
1761
1762
	nlines = (UPDATE_BUF_SIZE - pVNC->ublen) / bytesPerLine;
1763
	if (nlines == 0) {
1764
	    rfbLog("rfbSendRectEncodingRaw: send buffer too small for %d "
1765
		   "bytes per line\n", bytesPerLine);
1766
	    rfbCloseSock(cl->pScreen, cl->sock);
1767
	    return FALSE;
1768
	}
1769
    }
1770
}
1771
1772
1773
/*
1774
 * Send an empty rectangle with encoding field set to value of
1775
 * rfbEncodingLastRect to notify client that this is the last
1776
 * rectangle in framebuffer update ("LastRect" extension of RFB
1777
 * protocol).
1778
 */
1779
1780
static Bool
1781
rfbSendLastRectMarker(cl)
1782
    rfbClientPtr cl;
1783
{
1784
    VNCSCREENPTR(cl->pScreen);
1785
    rfbFramebufferUpdateRectHeader rect;
1786
1787
    if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
1788
	if (!rfbSendUpdateBuf(cl))
1789
	    return FALSE;
1790
    }
1791
1792
    rect.encoding = Swap32IfLE(rfbEncodingLastRect);
1793
    rect.r.x = 0;
1794
    rect.r.y = 0;
1795
    rect.r.w = 0;
1796
    rect.r.h = 0;
1797
1798
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader);
1799
    pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
1800
1801
    cl->rfbLastRectMarkersSent++;
1802
    cl->rfbLastRectBytesSent += sz_rfbFramebufferUpdateRectHeader;
1803
1804
    return TRUE;
1805
}
1806
1807
1808
/*
1809
 * Send the contents of pVNC->updateBuf.  Returns 1 if successful, -1 if
1810
 * not (errno should be set).
1811
 */
1812
1813
Bool
1814
rfbSendUpdateBuf(cl)
1815
    rfbClientPtr cl;
1816
{
1817
    VNCSCREENPTR(cl->pScreen);
1818
1819
    /*
1820
    int i;
1821
    for (i = 0; i < pVNC->ublen; i++) {
1822
	rfbLog("%02x ",((unsigned char *)pVNC->updateBuf)[i]);
1823
    }
1824
    rfbLog("\n");
1825
    */
1826
1827
    if (pVNC->ublen > 0 && WriteExact(cl->sock, (char*)pVNC->updateBuf, pVNC->ublen) < 0) {
1828
	rfbLogPerror("rfbSendUpdateBuf: write");
1829
	rfbCloseSock(cl->pScreen, cl->sock);
1830
	return FALSE;
1831
    }
1832
1833
    pVNC->ublen = 0;
1834
    return TRUE;
1835
}
1836
1837
1838
1839
/*
1840
 * rfbSendSetColourMapEntries sends a SetColourMapEntries message to the
1841
 * client, using values from the currently installed colormap.
1842
 */
1843
1844
Bool
1845
rfbSendSetColourMapEntries(cl, firstColour, nColours)
1846
    rfbClientPtr cl;
1847
    int firstColour;
1848
    int nColours;
1849
{
1850
#if !XFREE86VNC
1851
    VNCSCREENPTR(cl->pScreen);
1852
#endif
1853
    char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2];
1854
    rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf;
1855
    CARD16 *rgb = (CARD16 *)(&buf[sz_rfbSetColourMapEntriesMsg]);
1856
    EntryPtr pent;
1857
    EntryPtr redEntry, greenEntry, blueEntry;
1858
    unsigned short redPart, greenPart, bluePart;
1859
    int i, len;
1860
1861
    scme->type = rfbSetColourMapEntries;
1862
    scme->nColours = Swap16IfLE(nColours);
1863
1864
    len = sz_rfbSetColourMapEntriesMsg;
1865
1866
    /* PseudoColor */
1867
#if XFREE86VNC
1868
    if (miInstalledMaps[cl->pScreen->myNum]->class == PseudoColor) {
1869
#else
1870
    if (pVNC->rfbInstalledColormap->class == PseudoColor) {
1871
#endif
1872
      scme->firstColour = Swap16IfLE(firstColour);
1873
#if XFREE86VNC
1874
      pent = (EntryPtr)&miInstalledMaps[cl->pScreen->myNum]->red[firstColour];
1875
#else
1876
      pent = (EntryPtr)&pVNC->rfbInstalledColormap->red[firstColour];
1877
#endif
1878
      for (i = 0; i < nColours; i++) {
1879
  	  if (pent->fShared) {
1880
	      rgb[i*3] = Swap16IfLE(pent->co.shco.red->color);
1881
	      rgb[i*3+1] = Swap16IfLE(pent->co.shco.green->color);
1882
	      rgb[i*3+2] = Swap16IfLE(pent->co.shco.blue->color);
1883
	  } else {
1884
	      rgb[i*3] = Swap16IfLE(pent->co.local.red);
1885
	      rgb[i*3+1] = Swap16IfLE(pent->co.local.green);
1886
	      rgb[i*3+2] = Swap16IfLE(pent->co.local.blue);
1887
	  }
1888
	  pent++;
1889
      }
1890
    }
1891
1892
    else {
1893
1894
      /* Break the DirectColor pixel into its r/g/b components */
1895
#if XFREE86VNC
1896
      redPart   = (firstColour & miInstalledMaps[cl->pScreen->myNum]->pVisual->redMask)
1897
		  >> miInstalledMaps[cl->pScreen->myNum]->pVisual->offsetRed;
1898
      greenPart = (firstColour & miInstalledMaps[cl->pScreen->myNum]->pVisual->greenMask)
1899
		  >> miInstalledMaps[cl->pScreen->myNum]->pVisual->offsetGreen;
1900
      bluePart  = (firstColour & miInstalledMaps[cl->pScreen->myNum]->pVisual->blueMask)
1901
		  >> miInstalledMaps[cl->pScreen->myNum]->pVisual->offsetBlue;
1902
#else
1903
      redPart   = (firstColour & pVNC->rfbInstalledColormap->pVisual->redMask)
1904
		  >> pVNC->rfbInstalledColormap->pVisual->offsetRed;
1905
      greenPart = (firstColour & pVNC->rfbInstalledColormap->pVisual->greenMask)
1906
		  >> pVNC->rfbInstalledColormap->pVisual->offsetGreen;
1907
      bluePart  = (firstColour & pVNC->rfbInstalledColormap->pVisual->blueMask)
1908
		  >> pVNC->rfbInstalledColormap->pVisual->offsetBlue;
1909
#endif
1910
1911
      /*
1912
       * The firstColour field is only 16 bits. To support 24-bit pixels we
1913
       * sneak the red component in the 8-bit padding field which we renamed
1914
       * to redIndex. Green and blue are in firstColour (MSB, LSB respectively).
1915
       */
1916
      scme->redIndex    = Swap16IfLE(redPart);
1917
      scme->firstColour = Swap16IfLE((greenPart << 8) | bluePart);
1918
1919
#if XFREE86VNC
1920
      redEntry   = (EntryPtr)&miInstalledMaps[cl->pScreen->myNum]->red[redPart];
1921
      greenEntry = (EntryPtr)&miInstalledMaps[cl->pScreen->myNum]->green[greenPart];
1922
      blueEntry  = (EntryPtr)&miInstalledMaps[cl->pScreen->myNum]->blue[bluePart];
1923
#else
1924
      redEntry   = (EntryPtr)&pVNC->rfbInstalledColormap->red[redPart];
1925
      greenEntry = (EntryPtr)&pVNC->rfbInstalledColormap->green[greenPart];
1926
      blueEntry  = (EntryPtr)&pVNC->rfbInstalledColormap->blue[bluePart];
1927
#endif
1928
      for (i = 0; i < nColours; i++) {
1929
	  if (redEntry->fShared)
1930
	      rgb[i*3] = Swap16IfLE(redEntry->co.shco.red->color);
1931
	  else
1932
	      rgb[i*3] = Swap16IfLE(redEntry->co.local.red);
1933
1934
	  if (greenEntry->fShared)
1935
	      rgb[i*3+1] = Swap16IfLE(greenEntry->co.shco.green->color);
1936
	  else
1937
	      rgb[i*3+1] = Swap16IfLE(greenEntry->co.local.green);
1938
1939
	  if (blueEntry->fShared)
1940
	      rgb[i*3+2] = Swap16IfLE(blueEntry->co.shco.blue->color);
1941
	  else
1942
	      rgb[i*3+2] = Swap16IfLE(blueEntry->co.local.blue);
1943
1944
	  redEntry++;
1945
	  greenEntry++;
1946
	  blueEntry++;
1947
      }
1948
    }
1949
1950
    len += nColours * 3 * 2;
1951
1952
    if (WriteExact(cl->sock, buf, len) < 0) {
1953
	rfbLogPerror("rfbSendSetColourMapEntries: write");
1954
	rfbCloseSock(cl->pScreen, cl->sock);
1955
	return FALSE;
1956
    }
1957
    return TRUE;
1958
}
1959
1960
1961
/*
1962
 * rfbSendBell sends a Bell message to all the clients.
1963
 */
1964
1965
void
1966
rfbSendBell(void)
1967
{
1968
    rfbClientPtr cl, nextCl;
1969
    rfbBellMsg b;
1970
1971
    for (cl = rfbClientHead; cl; cl = nextCl) {
1972
	nextCl = cl->next;
1973
	b.type = rfbBell;
1974
	if (WriteExact(cl->sock, (char *)&b, sz_rfbBellMsg) < 0) {
1975
	    rfbLogPerror("rfbSendBell: write");
1976
	    rfbCloseSock(cl->pScreen, cl->sock);
1977
	}
1978
    }
1979
}
1980
1981
#ifdef CHROMIUM
1982
#ifdef sun
1983
extern int inet_aton(const char *cp, struct in_addr *inp);
1984
#endif
1985
1986
1987
/**
1988
 * This sends a ChromiumStart message to all VNC viewers running on the
1989
 * host named by ipaddress.
1990
 * This is done in response to an OpenGL/Chromium app calling
1991
 * XVncChromiumStart().
1992
 */
1993
void
1994
rfbSendChromiumStart(unsigned int ipaddress, unsigned int crServerPort,
1995
                     unsigned int mothershipPort)
1996
{
1997
    rfbClientPtr cl, nextCl;
1998
    rfbChromiumStartMsg scd;
1999
    struct in_addr ip;
2000
    unsigned int vncipaddress;
2001
2002
    /*rfbLog("Enter %s\n", __func__);*/
2003
    /* loop over vnc viewers/clients */
2004
    for (cl = rfbClientHead; cl; cl = nextCl) {
2005
	nextCl = cl->next;
2006
        /*rfbLog("%s: cl=%p enableCr=%d\n", __func__,
2007
          (void*) cl, cl->enableChromiumEncoding);
2008
        */
2009
	if (!cl->enableChromiumEncoding) {
2010
            /* viewer is not chromium-enhanced */
2011
	    continue;
2012
        }
2013
	inet_aton(cl->host, &ip);
2014
	memcpy(&vncipaddress, &ip, sizeof(unsigned int));
2015
        rfbLog("%s: ipaddr=0x%x vncipaddr=0x%x  cl->port=%d\n",
2016
               __func__, ipaddress, vncipaddress, cl->chromium_port);
2017
	if (ipaddress == vncipaddress /**&& !cl->chromium_port**/) {
2018
	    cl->chromium_port = crServerPort;
2019
	    cl->chromium_msport = mothershipPort;
2020
    	    scd.type = rfbChromiumStart;
2021
    	    scd.crServerPort = crServerPort;
2022
    	    scd.mothershipPort = mothershipPort;
2023
    	    if (WriteExact(cl->sock, (char *)&scd,
2024
		       sz_rfbChromiumStartMsg) < 0) {
2025
	    	rfbLogPerror("rfbSendChromiumStart: write");
2026
	    	rfbCloseSock(cl->pScreen, cl->sock);
2027
    	    }
2028
	    /* We only start one client at a time, so break now! */
2029
	    break;
2030
	}
2031
    }
2032
    /*rfbLog("Leave %s\n", __func__);*/
2033
}
2034
2035
2036
/**
2037
 * Begin monitoring the given X windowid.
2038
 * When we detect size/position/visibility changes we'll send a 
2039
 * rfbChromiumMoveResizeWindow, rfbChromiumClipList, or rfbChromiumWindowShow
2040
 * message to the VNC viewer, passing the corresponding Chromium window id.
2041
 */
2042
void
2043
rfbChromiumMonitorWindowID(unsigned int cr_windowid, unsigned long xwindowid)
2044
{
2045
    CRWindowTable *newRec, *wt, *nextWt = NULL;
2046
2047
    if (xwindowid && !cr_windowid) {
2048
        /* stop monitoring the X window, remove from list */
2049
        CRWindowTable *prev = NULL;
2050
        for (wt = windowTable; wt; wt = nextWt) {
2051
            nextWt = wt->next;
2052
            if (wt->XwinId == xwindowid) {
2053
                /* remove */
2054
                if (prev)
2055
                    prev->next = wt->next;
2056
                else
2057
                   windowTable = wt->next;
2058
                xfree(wt);
2059
            }
2060
            else {
2061
                prev = wt;
2062
            }
2063
        }
2064
        return;
2065
    }
2066
2067
    /* See if we're already monitoring this window */
2068
    for (wt = windowTable; wt; wt = nextWt) {
2069
        nextWt = wt->next;
2070
        /* and if so, update it's window ID */
2071
        if (wt->CRwinId == cr_windowid) {
2072
            wt->XwinId = xwindowid;
2073
            return;
2074
        }
2075
    }
2076
2077
    /* o.k, new window so create new slot information */
2078
    newRec = (CRWindowTable *)xalloc(sizeof(CRWindowTable));
2079
    if (!newRec) {
2080
        rfbLog("Out of memory allocating CRWindowTable.\n");
2081
        return;
2082
    }
2083
    
2084
    newRec->next = NULL;
2085
    newRec->CRwinId = cr_windowid;
2086
    newRec->XwinId = xwindowid;
2087
    newRec->clipRects = NULL;
2088
    newRec->numRects = 0;
2089
2090
    if (!windowTable) {
2091
        windowTable = newRec;
2092
    }
2093
    else {
2094
        for (wt = windowTable; wt; wt = nextWt) {
2095
            nextWt = wt->next;
2096
            if (!wt->next) /* found the next slot */
2097
                wt->next = newRec;
2098
        }
2099
    }
2100
}
2101
2102
2103
void
2104
rfbSendChromiumMoveResizeWindow(unsigned int winid, int x, int y, unsigned int w, unsigned int h)
2105
{
2106
    rfbClientPtr cl, nextCl;
2107
    rfbChromiumMoveResizeWindowMsg scm;
2108
2109
    for (cl = rfbClientHead; cl; cl = nextCl) {
2110
	nextCl = cl->next;
2111
	if (!cl->enableChromiumEncoding)
2112
	    continue;
2113
	if (cl->chromium_port) {
2114
    	    scm.type = rfbChromiumMoveResizeWindow;
2115
	    scm.winid = winid;
2116
	    scm.x = x;
2117
	    scm.y = y;
2118
	    scm.w = w;
2119
	    scm.h = h;
2120
    	    if (WriteExact(cl->sock, (char *)&scm,
2121
		       sz_rfbChromiumMoveResizeWindowMsg) < 0) {
2122
	    	rfbLogPerror("rfbSendChromiumMoveResizeWindow: write\n");
2123
	    	rfbCloseSock(cl->pScreen, cl->sock);
2124
		continue;
2125
    	    }
2126
	}
2127
    }
2128
}
2129
2130
void
2131
rfbSendChromiumClipList(unsigned int winid, BoxPtr pClipRects, int numClipRects)
2132
{
2133
    rfbClientPtr cl, nextCl;
2134
    rfbChromiumClipListMsg sccl;
2135
    int len = sizeof(BoxRec) * numClipRects;
2136
2137
    for (cl = rfbClientHead; cl; cl = nextCl) {
2138
	nextCl = cl->next;
2139
	if (!cl->enableChromiumEncoding)
2140
	    continue;
2141
	if (cl->chromium_port) {
2142
    	    sccl.type = rfbChromiumClipList;
2143
	    sccl.winid = winid;
2144
	    sccl.length = Swap32IfLE(len);
2145
    	    if (WriteExact(cl->sock, (char *)&sccl,
2146
		       sz_rfbChromiumClipListMsg) < 0) {
2147
	    	rfbLogPerror("rfbSendChromiumClipList: write\n");
2148
	    	rfbCloseSock(cl->pScreen, cl->sock);
2149
		continue;
2150
    	    }
2151
	    if (WriteExact(cl->sock, (char *)pClipRects, len) < 0) {
2152
	   	rfbLogPerror("rfbSendChromiumClipList: write\n");
2153
	    	rfbCloseSock(cl->pScreen, cl->sock);
2154
		continue;
2155
	    }
2156
	}
2157
    }
2158
}
2159
2160
void
2161
rfbSendChromiumWindowShow(unsigned int winid, unsigned int show)
2162
{
2163
    rfbClientPtr cl, nextCl;
2164
    rfbChromiumWindowShowMsg scws;
2165
2166
    for (cl = rfbClientHead; cl; cl = nextCl) {
2167
	nextCl = cl->next;
2168
	if (!cl->enableChromiumEncoding)
2169
	    continue;
2170
	if (cl->chromium_port) {
2171
    	    scws.type = rfbChromiumWindowShow;
2172
	    scws.winid = winid;
2173
	    scws.show = show;
2174
    	    if (WriteExact(cl->sock, (char *)&scws,
2175
		       sz_rfbChromiumWindowShowMsg) < 0) {
2176
	    	rfbLogPerror("rfbSendChromiumWindowShow: write\n");
2177
	    	rfbCloseSock(cl->pScreen, cl->sock);
2178
		continue;
2179
    	    }
2180
	}
2181
    }
2182
}
2183
2184
void
2185
rfbSendChromiumWindowDestroy(unsigned int winid)
2186
{
2187
    rfbClientPtr cl, nextCl;
2188
    rfbChromiumWindowDestroyMsg scwd;
2189
2190
    for (cl = rfbClientHead; cl; cl = nextCl) {
2191
	nextCl = cl->next;
2192
	if (!cl->enableChromiumEncoding)
2193
	    continue;
2194
	if (cl->chromium_port) {
2195
    	    scwd.type = rfbChromiumWindowDestroy;
2196
	    scwd.winid = winid;
2197
    	    if (WriteExact(cl->sock, (char *)&scwd,
2198
		       sz_rfbChromiumWindowDestroyMsg) < 0) {
2199
	    	rfbLogPerror("rfbSendChromiumWindowDestroy: write\n");
2200
	    	rfbCloseSock(cl->pScreen, cl->sock);
2201
		continue;
2202
    	    }
2203
	}
2204
    }
2205
}
2206
#endif /* CHROMIUM */
2207
2208
/*
2209
 * rfbSendServerCutText sends a ServerCutText message to all the clients.
2210
 */
2211
2212
void
2213
rfbSendServerCutText(char *str, int len)
2214
{
2215
    rfbClientPtr cl, nextCl = NULL;
2216
    rfbServerCutTextMsg sct;
2217
2218
    for (cl = rfbClientHead; cl; cl = nextCl) {
2219
	if (cl->state != RFB_NORMAL) continue;
2220
	nextCl = cl->next;
2221
	sct.type = rfbServerCutText;
2222
	sct.length = Swap32IfLE(len);
2223
	if (WriteExact(cl->sock, (char *)&sct,
2224
		       sz_rfbServerCutTextMsg) < 0) {
2225
	    rfbLogPerror("rfbSendServerCutText: write\n");
2226
	    rfbCloseSock(cl->pScreen, cl->sock);
2227
	    continue;
2228
	}
2229
	if (WriteExact(cl->sock, str, len) < 0) {
2230
	    rfbLogPerror("rfbSendServerCutText: write\n");
2231
	    rfbCloseSock(cl->pScreen, cl->sock);
2232
	}
2233
    }
2234
}
2235
2236
2237
2238
2239
/*****************************************************************************
2240
 *
2241
 * UDP can be used for keyboard and pointer events when the underlying
2242
 * network is highly reliable.  This is really here to support ORL's
2243
 * videotile, whose TCP implementation doesn't like sending lots of small
2244
 * packets (such as 100s of pen readings per second!).
2245
 */
2246
2247
void
2248
rfbNewUDPConnection(sock)
2249
    int sock;
2250
{
2251
    if (write(sock, &ptrAcceleration, 1) < 0) {
2252
	rfbLogPerror("rfbNewUDPConnection: write");
2253
    }
2254
}
2255
2256
/*
2257
 * Because UDP is a message based service, we can't read the first byte and
2258
 * then the rest of the packet separately like we do with TCP.  We will always
2259
 * get a whole packet delivered in one go, so we ask read() for the maximum
2260
 * number of bytes we can possibly get.
2261
 */
2262
2263
void
2264
rfbProcessUDPInput(ScreenPtr pScreen, int sock)
2265
{
2266
    VNCSCREENPTR(pScreen);
2267
    int n;
2268
    rfbClientToServerMsg msg;
2269
2270
    if ((n = read(sock, (char *)&msg, sizeof(msg))) <= 0) {
2271
	if (n < 0) {
2272
	    rfbLogPerror("rfbProcessUDPInput: read");
2273
	}
2274
	rfbDisconnectUDPSock(pScreen);
2275
	return;
2276
    }
2277
2278
    switch (msg.type) {
2279
2280
    case rfbKeyEvent:
2281
	if (n != sz_rfbKeyEventMsg) {
2282
	    rfbLog("rfbProcessUDPInput: key event incorrect length\n");
2283
	    rfbDisconnectUDPSock(pScreen);
2284
	    return;
2285
	}
2286
	if (!pVNC->rfbViewOnly) {
2287
	    KbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), 0);
2288
	}
2289
	break;
2290
2291
    case rfbPointerEvent:
2292
	if (n != sz_rfbPointerEventMsg) {
2293
	    rfbLog("rfbProcessUDPInput: ptr event incorrect length\n");
2294
	    rfbDisconnectUDPSock(pScreen);
2295
	    return;
2296
	}
2297
	if (!pVNC->rfbViewOnly) {
2298
	    PtrAddEvent(msg.pe.buttonMask,
2299
			Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), 0);
2300
	}
2301
	break;
2302
2303
    default:
2304
	rfbLog("rfbProcessUDPInput: unknown message type %d\n",
2305
	       msg.type);
2306
	rfbDisconnectUDPSock(pScreen);
2307
    }
2308
}
(-)xorg-server-1.4.orig/hw/vnc/rre.c (+324 lines)
Line 0 Link Here
1
/*
2
 * rre.c
3
 *
4
 * Routines to implement Rise-and-Run-length Encoding (RRE).  This
5
 * code is based on krw's original javatel rfbserver.
6
 *
7
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
8
 */
9
10
/*
11
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
12
 *
13
 *  This is free software; you can redistribute it and/or modify
14
 *  it under the terms of the GNU General Public License as published by
15
 *  the Free Software Foundation; either version 2 of the License, or
16
 *  (at your option) any later version.
17
 *
18
 *  This software is distributed in the hope that it will be useful,
19
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 *  GNU General Public License for more details.
22
 *
23
 *  You should have received a copy of the GNU General Public License
24
 *  along with this software; if not, write to the Free Software
25
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
26
 *  USA.
27
 */
28
#ifdef HAVE_DIX_CONFIG_H
29
#include <dix-config.h>
30
#endif
31
32
33
#include <stdio.h>
34
#include "rfb.h"
35
36
/*
37
 * rreBeforeBuf contains pixel data in the client's format.
38
 * rreAfterBuf contains the RRE encoded version.  If the RRE encoded version is
39
 * larger than the raw data or if it exceeds rreAfterBufSize then
40
 * raw encoding is used instead.
41
 */
42
43
static int rreBeforeBufSize = 0;
44
static unsigned char *rreBeforeBuf = NULL;
45
46
static int rreAfterBufSize = 0;
47
static unsigned char *rreAfterBuf = NULL;
48
static int rreAfterBufLen;
49
50
static int subrectEncode8(CARD8 *data, int w, int h);
51
static int subrectEncode16(CARD16 *data, int w, int h);
52
static int subrectEncode32(CARD32 *data, int w, int h);
53
static CARD32 getBgColour(char *data, int size, int bpp);
54
55
56
/*
57
 * rfbSendRectEncodingRRE - send a given rectangle using RRE encoding.
58
 */
59
60
Bool
61
rfbSendRectEncodingRRE(cl, x, y, w, h)
62
    rfbClientPtr cl;
63
    int x, y, w, h;
64
{
65
    VNCSCREENPTR(cl->pScreen);
66
    rfbFramebufferUpdateRectHeader rect;
67
    rfbRREHeader hdr;
68
    int nSubrects;
69
    int i;
70
    int maxRawSize = (pVNC->width * pVNC->height
71
		      * (cl->format.bitsPerPixel / 8));
72
73
    if (rreBeforeBufSize < maxRawSize) {
74
	rreBeforeBufSize = maxRawSize;
75
	if (rreBeforeBuf == NULL)
76
	    rreBeforeBuf = (unsigned char *)xalloc(rreBeforeBufSize);
77
	else
78
	    rreBeforeBuf = (unsigned char *)xrealloc(rreBeforeBuf, rreBeforeBufSize);
79
    }
80
81
    if (rreAfterBufSize < maxRawSize) {
82
	rreAfterBufSize = maxRawSize;
83
	if (rreAfterBuf == NULL)
84
	    rreAfterBuf = (unsigned char *)xalloc(rreAfterBufSize);
85
	else
86
	    rreAfterBuf = (unsigned char *)xrealloc(rreAfterBuf, rreAfterBufSize);
87
    }
88
89
    (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, 
90
		       &pVNC->rfbServerFormat,
91
		       &cl->format, rreBeforeBuf,
92
		       pVNC->paddedWidthInBytes, w, h, x, y);
93
94
    switch (cl->format.bitsPerPixel) {
95
    case 8:
96
	nSubrects = subrectEncode8((CARD8 *)rreBeforeBuf, w, h);
97
	break;
98
    case 16:
99
	nSubrects = subrectEncode16((CARD16 *)rreBeforeBuf, w, h);
100
	break;
101
    case 32:
102
	nSubrects = subrectEncode32((CARD32 *)rreBeforeBuf, w, h);
103
	break;
104
    default:
105
	rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel);
106
	exit(1);
107
    }
108
	
109
    if (nSubrects < 0) {
110
111
	/* RRE encoding was too large, use raw */
112
113
	return rfbSendRectEncodingRaw(cl, x, y, w, h);
114
    }
115
116
    cl->rfbRectanglesSent[rfbEncodingRRE]++;
117
    cl->rfbBytesSent[rfbEncodingRRE] += (sz_rfbFramebufferUpdateRectHeader
118
					 + sz_rfbRREHeader + rreAfterBufLen);
119
120
    if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader
121
	> UPDATE_BUF_SIZE)
122
    {
123
	if (!rfbSendUpdateBuf(cl))
124
	    return FALSE;
125
    }
126
127
    rect.r.x = Swap16IfLE(x);
128
    rect.r.y = Swap16IfLE(y);
129
    rect.r.w = Swap16IfLE(w);
130
    rect.r.h = Swap16IfLE(h);
131
    rect.encoding = Swap32IfLE(rfbEncodingRRE);
132
133
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,
134
	   sz_rfbFramebufferUpdateRectHeader);
135
    pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
136
137
    hdr.nSubrects = Swap32IfLE(nSubrects);
138
139
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&hdr, sz_rfbRREHeader);
140
    pVNC->ublen += sz_rfbRREHeader;
141
142
    for (i = 0; i < rreAfterBufLen;) {
143
144
	int bytesToCopy = UPDATE_BUF_SIZE - pVNC->ublen;
145
146
	if (i + bytesToCopy > rreAfterBufLen) {
147
	    bytesToCopy = rreAfterBufLen - i;
148
	}
149
150
	memcpy(&pVNC->updateBuf[pVNC->ublen], &rreAfterBuf[i], bytesToCopy);
151
152
	pVNC->ublen += bytesToCopy;
153
	i += bytesToCopy;
154
155
	if (pVNC->ublen == UPDATE_BUF_SIZE) {
156
	    if (!rfbSendUpdateBuf(cl))
157
		return FALSE;
158
	}
159
    }
160
161
    return TRUE;
162
}
163
164
165
166
/*
167
 * subrectEncode() encodes the given multicoloured rectangle as a background 
168
 * colour overwritten by single-coloured rectangles.  It returns the number 
169
 * of subrectangles in the encoded buffer, or -1 if subrect encoding won't
170
 * fit in the buffer.  It puts the encoded rectangles in rreAfterBuf.  The
171
 * single-colour rectangle partition is not optimal, but does find the biggest
172
 * horizontal or vertical rectangle top-left anchored to each consecutive 
173
 * coordinate position.
174
 *
175
 * The coding scheme is simply [<bgcolour><subrect><subrect>...] where each 
176
 * <subrect> is [<colour><x><y><w><h>].
177
 */
178
179
#define DEFINE_SUBRECT_ENCODE(bpp)					      \
180
static int								      \
181
subrectEncode##bpp(data,w,h)						      \
182
    CARD##bpp *data;							      \
183
    int w;								      \
184
    int h;								      \
185
{									      \
186
    CARD##bpp cl;							      \
187
    rfbRectangle subrect;						      \
188
    int x,y;								      \
189
    int i,j;								      \
190
    int hx=0,hy,vx=0,vy;						      \
191
    int hyflag;								      \
192
    CARD##bpp *seg;							      \
193
    CARD##bpp *line;							      \
194
    int hw,hh,vw,vh;							      \
195
    int thex,they,thew,theh;						      \
196
    int numsubs = 0;							      \
197
    int newLen;								      \
198
    CARD##bpp bg = (CARD##bpp)getBgColour((char*)data,w*h,bpp);		      \
199
									      \
200
    *((CARD##bpp*)rreAfterBuf) = bg;					      \
201
									      \
202
    rreAfterBufLen = (bpp/8);						      \
203
									      \
204
    for (y=0; y<h; y++) {						      \
205
      line = data+(y*w);						      \
206
      for (x=0; x<w; x++) {						      \
207
        if (line[x] != bg) {						      \
208
          cl = line[x];							      \
209
          hy = y-1;							      \
210
          hyflag = 1;							      \
211
          for (j=y; j<h; j++) {						      \
212
            seg = data+(j*w);						      \
213
            if (seg[x] != cl) {break;}					      \
214
            i = x;							      \
215
            while ((seg[i] == cl) && (i < w)) i += 1;			      \
216
            i -= 1;							      \
217
            if (j == y) vx = hx = i;					      \
218
            if (i < vx) vx = i;						      \
219
            if ((hyflag > 0) && (i >= hx)) {hy += 1;} else {hyflag = 0;}      \
220
          }								      \
221
          vy = j-1;							      \
222
									      \
223
          /*  We now have two possible subrects: (x,y,hx,hy) and (x,y,vx,vy)  \
224
           *  We'll choose the bigger of the two.			      \
225
           */								      \
226
          hw = hx-x+1;							      \
227
          hh = hy-y+1;							      \
228
          vw = vx-x+1;							      \
229
          vh = vy-y+1;							      \
230
									      \
231
          thex = x;							      \
232
          they = y;							      \
233
									      \
234
          if ((hw*hh) > (vw*vh)) {					      \
235
            thew = hw;							      \
236
            theh = hh;							      \
237
          } else {							      \
238
            thew = vw;							      \
239
            theh = vh;							      \
240
          }								      \
241
									      \
242
          subrect.x = Swap16IfLE(thex);					      \
243
          subrect.y = Swap16IfLE(they);					      \
244
          subrect.w = Swap16IfLE(thew);					      \
245
          subrect.h = Swap16IfLE(theh);					      \
246
									      \
247
	  newLen = rreAfterBufLen + (bpp/8) + sz_rfbRectangle;		      \
248
          if ((newLen > (w * h * (bpp/8))) || (newLen > rreAfterBufSize))     \
249
	    return -1;							      \
250
									      \
251
	  numsubs += 1;							      \
252
	  *((CARD##bpp*)(rreAfterBuf + rreAfterBufLen)) = cl;		      \
253
	  rreAfterBufLen += (bpp/8);					      \
254
	  memcpy(&rreAfterBuf[rreAfterBufLen],&subrect,sz_rfbRectangle);      \
255
	  rreAfterBufLen += sz_rfbRectangle;				      \
256
									      \
257
          /*								      \
258
           * Now mark the subrect as done.				      \
259
           */								      \
260
          for (j=they; j < (they+theh); j++) {				      \
261
            for (i=thex; i < (thex+thew); i++) {			      \
262
              data[j*w+i] = bg;						      \
263
            }								      \
264
          }								      \
265
        }								      \
266
      }									      \
267
    }									      \
268
									      \
269
    return numsubs;							      \
270
}
271
272
DEFINE_SUBRECT_ENCODE(8)
273
DEFINE_SUBRECT_ENCODE(16)
274
DEFINE_SUBRECT_ENCODE(32)
275
276
277
/*
278
 * getBgColour() gets the most prevalent colour in a byte array.
279
 */
280
static CARD32
281
getBgColour(data,size,bpp)
282
    char *data;
283
    int size;
284
    int bpp;
285
{
286
    
287
#define NUMCLRS 256
288
  
289
  static int counts[NUMCLRS];
290
  int i,j,k;
291
292
  int maxcount = 0;
293
  CARD8 maxclr = 0;
294
295
  if (bpp != 8) {
296
    if (bpp == 16) {
297
      return ((CARD16 *)data)[0];
298
    } else if (bpp == 32) {
299
      return ((CARD32 *)data)[0];
300
    } else {
301
      rfbLog("getBgColour: bpp %d?\n",bpp);
302
      exit(1);
303
    }
304
  }
305
306
  for (i=0; i<NUMCLRS; i++) {
307
    counts[i] = 0;
308
  }
309
310
  for (j=0; j<size; j++) {
311
    k = (int)(((CARD8 *)data)[j]);
312
    if (k >= NUMCLRS) {
313
      rfbLog("getBgColour: unusual colour = %d\n", k);
314
      exit(1);
315
    }
316
    counts[k] += 1;
317
    if (counts[k] > maxcount) {
318
      maxcount = counts[k];
319
      maxclr = ((CARD8 *)data)[j];
320
    }
321
  }
322
  
323
  return maxclr;
324
}
(-)xorg-server-1.4.orig/hw/vnc/sockets.c (+656 lines)
Line 0 Link Here
1
/*
2
 * sockets.c - deal with TCP & UDP sockets.
3
 *
4
 * This code should be independent of any changes in the RFB protocol.  It just
5
 * deals with the X server scheduling stuff, calling rfbNewClientConnection and
6
 * rfbProcessClientMessage to actually deal with the protocol.  If a socket
7
 * needs to be closed for any reason then rfbCloseSock should be called, and
8
 * this in turn will call rfbClientConnectionGone.  To make an active
9
 * connection out, call rfbConnect - note that this does _not_ call
10
 * rfbNewClientConnection.
11
 *
12
 * This file is divided into two types of function.  Those beginning with
13
 * "rfb" are specific to sockets using the RFB protocol.  Those without the
14
 * "rfb" prefix are more general socket routines (which are used by the http
15
 * code).
16
 *
17
 * Thanks to Karl Hakimian for pointing out that some platforms return EAGAIN
18
 * not EWOULDBLOCK.
19
 *
20
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
21
 */
22
23
/*
24
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
25
 *
26
 *  This is free software; you can redistribute it and/or modify
27
 *  it under the terms of the GNU General Public License as published by
28
 *  the Free Software Foundation; either version 2 of the License, or
29
 *  (at your option) any later version.
30
 *
31
 *  This software is distributed in the hope that it will be useful,
32
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
33
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34
 *  GNU General Public License for more details.
35
 *
36
 *  You should have received a copy of the GNU General Public License
37
 *  along with this software; if not, write to the Free Software
38
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
39
 *  USA.
40
 */
41
#ifdef HAVE_DIX_CONFIG_H
42
#include <dix-config.h>
43
#endif
44
45
46
#include <stdio.h>
47
#include <sys/types.h>
48
#include <sys/time.h>
49
#include <sys/socket.h>
50
#include <netinet/in.h>
51
#include <netinet/tcp.h>
52
#include <arpa/inet.h>
53
#include <netdb.h>
54
#include <fcntl.h>
55
#include <errno.h>
56
#include "windowstr.h"
57
58
#ifndef USE_LIBWRAP
59
#define USE_LIBWRAP 0
60
#endif
61
#if USE_LIBWRAP
62
#include <syslog.h>
63
#include <tcpd.h>
64
int allow_severity = LOG_INFO;
65
int deny_severity = LOG_WARNING;
66
#endif
67
68
#include "rfb.h"
69
70
int rfbMaxClientWait = 20000;	/* time (ms) after which we decide client has
71
				   gone away - needed to stop us hanging */
72
73
static struct sockaddr_in udpRemoteAddr;
74
75
/*
76
 * rfbInitSockets sets up the TCP and UDP sockets to listen for RFB
77
 * connections.  It does nothing if called again.
78
 */
79
80
Bool
81
rfbInitSockets(ScreenPtr pScreen)
82
{
83
    VNCSCREENPTR(pScreen);
84
85
    if (inetdSock != -1) {
86
	const int one = 1;
87
88
	if (fcntl(inetdSock, F_SETFL, O_NONBLOCK) < 0) {
89
	    rfbLogPerror("fcntl");
90
	    return FALSE;
91
	}
92
93
	if (setsockopt(inetdSock, IPPROTO_TCP, TCP_NODELAY,
94
		       (char *)&one, sizeof(one)) < 0) {
95
	    rfbLogPerror("setsockopt");
96
	    return FALSE;
97
	}
98
99
    	AddEnabledDevice(inetdSock);
100
    	FD_ZERO(&pVNC->allFds);
101
    	FD_SET(inetdSock, &pVNC->allFds);
102
    	pVNC->maxFd = inetdSock;
103
	return TRUE;
104
    }
105
106
    if (pVNC->rfbPort == 0) {
107
	pVNC->rfbPort = 5900 + atoi(display) + pScreen->myNum;
108
    }
109
110
    if ((pVNC->rfbListenSock = ListenOnTCPPort(pScreen, pVNC->rfbPort)) < 0) {
111
	rfbLogPerror("ListenOnTCPPort");
112
	pVNC->rfbPort = 0;
113
	return FALSE;
114
    }
115
116
    rfbLog("Listening for VNC connections on TCP port %d\n", pVNC->rfbPort);
117
118
    AddEnabledDevice(pVNC->rfbListenSock);
119
120
    FD_ZERO(&pVNC->allFds);
121
    FD_SET(pVNC->rfbListenSock, &pVNC->allFds);
122
    pVNC->maxFd = pVNC->rfbListenSock;
123
124
    if (pVNC->udpPort != 0) {
125
	rfbLog("rfbInitSockets: listening for input on UDP port %d\n",pVNC->udpPort);
126
127
	if ((pVNC->udpSock = ListenOnUDPPort(pScreen, pVNC->udpPort)) < 0) {
128
	    rfbLogPerror("ListenOnUDPPort");
129
	    return FALSE;
130
	}
131
	AddEnabledDevice(pVNC->udpSock);
132
	FD_SET(pVNC->udpSock, &pVNC->allFds);
133
	pVNC->maxFd = max(pVNC->udpSock,pVNC->maxFd);
134
    }
135
   
136
    return TRUE;
137
}
138
139
140
/*
141
 * rfbCheckFds is called from ProcessInputEvents to check for input on the RFB
142
 * socket(s).  If there is input to process, the appropriate function in the
143
 * RFB server code will be called (rfbNewClientConnection,
144
 * rfbProcessClientMessage, etc).
145
 */
146
147
void
148
rfbCheckFds(ScreenPtr pScreen)
149
{
150
    VNCSCREENPTR(pScreen);
151
#if XFREE86VNC
152
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
153
#endif
154
    int nfds;
155
    fd_set fds;
156
    struct timeval tv;
157
    struct sockaddr_in addr;
158
    SOCKLEN_T addrlen = sizeof(addr);
159
    char buf[6];
160
    const int one = 1;
161
    int sock;
162
    static Bool inetdInitDone = FALSE;
163
164
    if (!inetdInitDone && inetdSock != -1) {
165
	rfbNewClientConnection(pScreen, inetdSock); 
166
	inetdInitDone = TRUE;
167
    }
168
169
    memcpy((char *)&fds, (char *)&pVNC->allFds, sizeof(fd_set));
170
    tv.tv_sec = 0;
171
    tv.tv_usec = 0;
172
    nfds = select(pVNC->maxFd + 1, &fds, NULL, NULL, &tv);
173
    if (nfds == 0) {
174
	return;
175
    }
176
    if (nfds < 0) {
177
	if (errno != EINTR)
178
		rfbLogPerror("rfbCheckFds: select");
179
	return;
180
    }
181
182
    if (pVNC->rfbListenSock != -1 && FD_ISSET(pVNC->rfbListenSock, &fds)) {
183
184
	if ((sock = accept(pVNC->rfbListenSock,
185
			   (struct sockaddr *)&addr, &addrlen)) < 0) {
186
	    rfbLogPerror("rfbCheckFds: accept");
187
	    return;
188
	}
189
190
	if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
191
	    rfbLogPerror("rfbCheckFds: fcntl");
192
	    close(sock);
193
	    return;
194
	}
195
196
	if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
197
		       (char *)&one, sizeof(one)) < 0) {
198
	    rfbLogPerror("rfbCheckFds: setsockopt");
199
	    close(sock);
200
	    return;
201
	}
202
203
	rfbLog("\n");
204
205
#if USE_LIBWRAP
206
        if (!hosts_ctl("Xvnc", STRING_UNKNOWN, inet_ntoa(addr.sin_addr),
207
                       STRING_UNKNOWN)) {
208
          rfbLog("Rejected connection from client %s\n",
209
                 inet_ntoa(addr.sin_addr));
210
          close(sock);
211
          return;
212
        }
213
#endif
214
215
	rfbLog("Got VNC connection from client %s\n", inet_ntoa(addr.sin_addr));
216
217
	AddEnabledDevice(sock);
218
	FD_SET(sock, &pVNC->allFds);
219
	pVNC->maxFd = max(sock,pVNC->maxFd);
220
221
	rfbNewClientConnection(pScreen, sock);
222
223
	FD_CLR(pVNC->rfbListenSock, &fds);
224
	if (--nfds == 0)
225
	    return;
226
    }
227
228
    if ((pVNC->udpSock != -1) && FD_ISSET(pVNC->udpSock, &fds)) {
229
230
	if (recvfrom(pVNC->udpSock, buf, 1, MSG_PEEK,
231
		     (struct sockaddr *)&addr, &addrlen) < 0) {
232
233
	    rfbLogPerror("rfbCheckFds: UDP: recvfrom");
234
	    rfbDisconnectUDPSock(pScreen);
235
236
	} else {
237
238
	    if (!pVNC->udpSockConnected ||
239
		(memcmp(&addr, &udpRemoteAddr, addrlen) != 0))
240
	    {
241
		/* new remote end */
242
		rfbLog("rfbCheckFds: UDP: got connection\n");
243
244
		memcpy(&udpRemoteAddr, &addr, addrlen);
245
		pVNC->udpSockConnected = TRUE;
246
247
		if (connect(pVNC->udpSock,
248
			    (struct sockaddr *)&addr, addrlen) < 0) {
249
		    rfbLogPerror("rfbCheckFds: UDP: connect");
250
		    rfbDisconnectUDPSock(pScreen);
251
		    return;
252
		}
253
254
		rfbNewUDPConnection(pVNC->udpSock);
255
	    }
256
257
	    rfbProcessUDPInput(pScreen, pVNC->udpSock);
258
	}
259
260
	FD_CLR(pVNC->udpSock, &fds);
261
	if (--nfds == 0)
262
	    return;
263
    }
264
265
    for (sock = 0; sock <= pVNC->maxFd; sock++) {
266
	if (FD_ISSET(sock, &fds) && FD_ISSET(sock, &pVNC->allFds)) {
267
#if XFREE86VNC
268
	    if (!pScrn->vtSema)
269
		rfbCloseSock(pScreen, sock);
270
	    else
271
#endif
272
	    	rfbProcessClientMessage(pScreen, sock);
273
	}
274
    }
275
}
276
277
278
void
279
rfbDisconnectUDPSock(ScreenPtr pScreen)
280
{
281
    VNCSCREENPTR(pScreen);
282
    pVNC->udpSockConnected = FALSE;
283
}
284
285
286
void
287
rfbCloseSock(ScreenPtr pScreen, int sock)
288
{
289
    VNCSCREENPTR(pScreen);
290
    close(sock);
291
    RemoveEnabledDevice(sock);
292
    FD_CLR(sock, &pVNC->allFds);
293
    rfbClientConnectionGone(sock);
294
    if (sock == inetdSock)
295
	GiveUp(0);
296
}
297
298
#if 0
299
/*
300
 * rfbWaitForClient can be called to wait for the RFB client to send us a
301
 * message.  When one is received it is processed by calling
302
 * rfbProcessClientMessage().
303
 */
304
305
void
306
rfbWaitForClient(sock)
307
    int sock;
308
{
309
    int n;
310
    fd_set fds;
311
    struct timeval tv;
312
313
    FD_ZERO(&fds);
314
    FD_SET(sock, &fds);
315
    tv.tv_sec = rfbMaxClientWait / 1000;
316
    tv.tv_usec = (rfbMaxClientWait % 1000) * 1000;
317
    n = select(sock+1, &fds, NULL, NULL, &tv);
318
    if (n < 0) {
319
	rfbLogPerror("rfbWaitForClient: select");
320
	exit(1);
321
    }
322
    if (n == 0) {
323
	rfbCloseSock(sock);
324
	return;
325
    }
326
327
    rfbProcessClientMessage(sock);
328
}
329
#endif
330
331
/*
332
 * rfbConnect is called to make a connection out to a given TCP address.
333
 */
334
335
int
336
rfbConnect(ScreenPtr pScreen, char *host, int port)
337
{
338
    VNCSCREENPTR(pScreen);
339
    int sock;
340
    int one = 1;
341
342
    rfbLog("\n");
343
    rfbLog("Making connection to client on host %s port %d\n",
344
	   host,port);
345
346
    if ((sock = ConnectToTcpAddr(host, port)) < 0) {
347
	rfbLogPerror("connection failed");
348
	return -1;
349
    }
350
351
    if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
352
	rfbLogPerror("fcntl failed");
353
	close(sock);
354
	return -1;
355
    }
356
357
    if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
358
		   (char *)&one, sizeof(one)) < 0) {
359
	rfbLogPerror("setsockopt failed");
360
	close(sock);
361
	return -1;
362
    }
363
364
    AddEnabledDevice(sock);
365
    FD_SET(sock, &pVNC->allFds);
366
    pVNC->maxFd = max(sock,pVNC->maxFd);
367
368
    return sock;
369
}
370
371
372
373
374
/*
375
 * ReadExact reads an exact number of bytes on a TCP socket.  Returns 1 if
376
 * those bytes have been read, 0 if the other end has closed, or -1 if an error
377
 * occurred (errno is set to ETIMEDOUT if it timed out).
378
 */
379
380
int
381
ReadExact(sock, buf, len)
382
    int sock;
383
    char *buf;
384
    int len;
385
{
386
    int n;
387
    fd_set fds;
388
    int tries = 5;
389
    struct timeval tv;
390
391
    while (len > 0) {
392
	n = read(sock, buf, len);
393
394
	if (n > 0) {
395
396
	    buf += n;
397
	    len -= n;
398
399
	} else if (n == 0) {
400
401
	    return 0;
402
403
	} else {
404
	    if (errno != EWOULDBLOCK && errno != EAGAIN) {
405
		return n;
406
	    }
407
408
	    do {
409
	   	FD_ZERO(&fds);
410
	    	FD_SET(sock, &fds);
411
	    	tv.tv_sec = rfbMaxClientWait / 1000;
412
	    	tv.tv_usec = (rfbMaxClientWait % 1000) * 1000;
413
	    	n = select(sock+1, &fds, NULL, NULL, &tv);
414
		tries--;
415
		
416
	    /* We really need to retry if we get EINTR, so spin */
417
	    /* If after 5 attempts we're still broke, abort.... */
418
419
	    } while ((n < 0 && errno == EINTR) && tries > 0);
420
421
	    if (n < 0) {
422
		rfbLogPerror("ReadExact: select");
423
		return n;
424
	    }
425
	    if (n == 0) {
426
		errno = ETIMEDOUT;
427
		return -1;
428
	    }
429
	}
430
    }
431
    return 1;
432
}
433
434
435
436
/*
437
 * WriteExact writes an exact number of bytes on a TCP socket.  Returns 1 if
438
 * those bytes have been written, or -1 if an error occurred (errno is set to
439
 * ETIMEDOUT if it timed out).
440
 */
441
442
int
443
WriteExact(sock, buf, len)
444
    int sock;
445
    char *buf;
446
    int len;
447
{
448
    int n;
449
    fd_set fds;
450
    struct timeval tv;
451
#if 0
452
    int totalTimeWaited = 0;
453
#endif
454
455
    while (len > 0) {
456
	n = write(sock, buf, len);
457
458
	if (n > 0) {
459
460
	    buf += n;
461
	    len -= n;
462
463
	} else if (n == 0) {
464
465
	    rfbLog("WriteExact: write returned 0?\n");
466
	    return -1;
467
468
	} else {
469
	    if (errno != EWOULDBLOCK && errno != EAGAIN) {
470
		return n;
471
	    }
472
473
#if 0
474
	    /* Retry every 5 seconds until we exceed rfbMaxClientWait.  We
475
	       need to do this because select doesn't necessarily return
476
	       immediately when the other end has gone away */
477
478
	    FD_ZERO(&fds);
479
	    FD_SET(sock, &fds);
480
	    tv.tv_sec = 5;
481
	    tv.tv_usec = 0;
482
#else
483
	    /* We're in the WakeupHandler now, so don't wait */
484
485
	    FD_ZERO(&fds);
486
	    FD_SET(sock, &fds);
487
	    tv.tv_sec = 0;
488
	    tv.tv_usec = 0;
489
#endif
490
	    n = select(sock+1, NULL, &fds, NULL, &tv);
491
#if 0
492
	    if (n < 0) {
493
		rfbLogPerror("WriteExact: select");
494
		return n;
495
	    }
496
	    if (n == 0) {
497
		totalTimeWaited += 5000;
498
		if (totalTimeWaited >= rfbMaxClientWait) {
499
		    errno = ETIMEDOUT;
500
		    return -1;
501
		}
502
	    } else {
503
		totalTimeWaited = 0;
504
	    }
505
#endif
506
	}
507
    }
508
    return 1;
509
}
510
511
512
int
513
ListenOnTCPPort(ScreenPtr pScreen, int port)
514
{
515
    VNCSCREENPTR(pScreen);
516
    struct sockaddr_in addr;
517
    int sock;
518
    int one = 1;
519
520
    memset(&addr, 0, sizeof(addr));
521
    addr.sin_family = AF_INET;
522
    addr.sin_port = htons(port);
523
    addr.sin_addr.s_addr = pVNC->interface.s_addr;
524
525
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
526
	return -1;
527
    }
528
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
529
		   (char *)&one, sizeof(one)) < 0) {
530
	close(sock);
531
	return -1;
532
    }
533
    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
534
	close(sock);
535
	return -1;
536
    }
537
    if (listen(sock, 5) < 0) {
538
	close(sock);
539
	return -1;
540
    }
541
542
    return sock;
543
}
544
545
546
int
547
ConnectToTcpAddr(host, port)
548
    char *host;
549
    int port;
550
{
551
    struct hostent *hp;
552
    int sock, n;
553
    struct sockaddr_in addr;
554
    int tries = 5;
555
556
    memset(&addr, 0, sizeof(addr));
557
    addr.sin_family = AF_INET;
558
    addr.sin_port = htons(port);
559
560
    if ((addr.sin_addr.s_addr = inet_addr(host)) == -1)
561
    {
562
	if (!(hp = gethostbyname(host))) {
563
	    errno = EINVAL;
564
	    return -1;
565
	}
566
	addr.sin_addr.s_addr = *(unsigned long *)hp->h_addr;
567
    }
568
569
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
570
	return -1;
571
    }
572
573
    do {
574
    	sock = socket(AF_INET, SOCK_STREAM, 0);
575
	tries--;
576
577
	/* We really need to retry if we get EINTR, so spin */
578
	/* If after 5 attempts we're still broke, abort.... */
579
580
    } while ((sock < 0 && errno == EINTR) && tries > 0);
581
582
    if (sock < 0) {
583
	return -1;
584
    }
585
586
    tries = 5;
587
588
    do {
589
    	n = connect(sock, (struct sockaddr *)&addr, (sizeof(addr)));
590
	tries--;
591
592
	/* We really need to retry if we get EINTR, so spin */
593
	/* If after 5 attempts we're still broke, abort.... */
594
595
    } while ((n < 0 && errno == EINTR) && tries > 0);
596
597
    if (n < 0) {
598
	close(sock);
599
	return -1;
600
    }
601
602
    return sock;
603
}
604
605
606
int
607
ListenOnUDPPort(ScreenPtr pScreen, int port)
608
{
609
    VNCSCREENPTR(pScreen);
610
    struct sockaddr_in addr;
611
    int sock;
612
    int one = 1;
613
614
    memset(&addr, 0, sizeof(addr));
615
    addr.sin_family = AF_INET;
616
    addr.sin_port = htons(port);
617
    addr.sin_addr.s_addr = pVNC->interface.s_addr;
618
619
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
620
	return -1;
621
    }
622
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
623
		   (char *)&one, sizeof(one)) < 0) {
624
	return -1;
625
    }
626
    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
627
	return -1;
628
    }
629
630
    return sock;
631
}
632
633
#if 0
634
/*
635
 * rdpInitSockets sets up the TCP for RDP
636
 * connections.  It does nothing if called again.
637
 */
638
639
Bool
640
rdpInitSockets(ScreenPtr pScreen)
641
{
642
    VNCSCREENPTR(pScreen);
643
644
    if ((pVNC->rdpListenSock = ListenOnTCPPort(pScreen, pVNC->rdpPort)) < 0) {
645
	rfbLogPerror("ListenOnTCPPort");
646
	pVNC->rdpPort = 0;
647
	return FALSE;
648
    }
649
650
    rfbLog("Listening for RDP connections on TCP port %d\n", pVNC->rdpPort);
651
652
    AddEnabledDevice(pVNC->rdpListenSock);
653
654
    return TRUE;
655
}
656
#endif
(-)xorg-server-1.4.orig/hw/vnc/sprite.c (+2452 lines)
Line 0 Link Here
1
/*
2
 * sprite.c
3
 *
4
 * software sprite routines - based on misprite
5
 *
6
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
7
 */
8
9
/*
10
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
11
 *
12
 *  This is free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 2 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  This software is distributed in the hope that it will be useful,
18
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 *  GNU General Public License for more details.
21
 *
22
 *  You should have received a copy of the GNU General Public License
23
 *  along with this software; if not, write to the Free Software
24
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
25
 *  USA.
26
 */
27
28
/* $XConsortium: misprite.c,v 5.47 94/04/17 20:27:53 dpw Exp $ */
29
30
/*
31
32
Copyright (c) 1989  X Consortium
33
34
Permission is hereby granted, free of charge, to any person obtaining a copy
35
of this software and associated documentation files (the "Software"), to deal
36
in the Software without restriction, including without limitation the rights
37
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38
copies of the Software, and to permit persons to whom the Software is
39
furnished to do so, subject to the following conditions:
40
41
The above copyright notice and this permission notice shall be included in
42
all copies or substantial portions of the Software.
43
44
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
47
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
48
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
49
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
50
51
Except as contained in this notice, the name of the X Consortium shall not be
52
used in advertising or otherwise to promote the sale, use or other dealings
53
in this Software without prior written authorization from the X Consortium.
54
*/
55
#ifdef HAVE_DIX_CONFIG_H
56
#include <dix-config.h>
57
#endif
58
59
60
#include "rfb.h"
61
# include   <X11/X.h>
62
# include   <X11/Xproto.h>
63
# include   <X11/fonts/font.h>
64
# include   <X11/fonts/fontstruct.h>
65
# include   "misc.h"
66
# include   "pixmapstr.h"
67
# include   "input.h"
68
# include   "mi.h"
69
# include   "cursorstr.h"
70
# include   "scrnintstr.h"
71
# include   "colormapst.h"
72
# include   "windowstr.h"
73
# include   "gcstruct.h"
74
# include   "mipointer.h"
75
# include   "spritest.h"
76
# include   "dixfontstr.h"
77
#ifdef RENDER
78
# include   "mipict.h"
79
#endif
80
81
/*
82
 * screen wrappers
83
 */
84
85
static int  rfbSpriteScreenIndex;
86
static unsigned long rfbSpriteGeneration = 0;
87
88
static Bool	    rfbSpriteCloseScreen(int i, ScreenPtr pScreen);
89
static void	    rfbSpriteGetImage(DrawablePtr pDrawable, int sx, int sy,
90
				     int w, int h, unsigned int format,
91
				     unsigned long planemask, char *pdstLine);
92
static void	    rfbSpriteGetSpans(DrawablePtr pDrawable, int wMax,
93
				     DDXPointPtr ppt, int *pwidth, int nspans,
94
			     char *pdstStart);
95
static void	    rfbSpriteSourceValidate(DrawablePtr pDrawable, int x, int y,
96
					   int width, int height);
97
static Bool	    rfbSpriteCreateGC(GCPtr pGC);
98
static void	    rfbSpriteBlockHandler(int i, pointer blockData,
99
					 pointer pTimeout,
100
					 pointer pReadMask);
101
static void	    rfbSpriteInstallColormap(ColormapPtr pMap);
102
static void	    rfbSpriteStoreColors(ColormapPtr pMap, int ndef,
103
					xColorItem *pdef);
104
105
static void	    rfbSpritePaintWindowBackground(WindowPtr pWin,
106
						  RegionPtr pRegion, int what);
107
static void	    rfbSpritePaintWindowBorder(WindowPtr pWin,
108
					      RegionPtr pRegion, int what);
109
static void	    rfbSpriteCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
110
				       RegionPtr pRegion);
111
static void	    rfbSpriteClearToBackground(WindowPtr pWin, int x, int y,
112
					      int w, int h,
113
					      Bool generateExposures);
114
115
#ifdef RENDER
116
static void	    rfbSpriteComposite(CARD8	op,
117
				      PicturePtr pSrc,
118
				      PicturePtr pMask,
119
				      PicturePtr pDst,
120
				      INT16	xSrc,
121
				      INT16	ySrc,
122
				      INT16	xMask,
123
				      INT16	yMask,
124
				      INT16	xDst,
125
				      INT16	yDst,
126
				      CARD16	width,
127
				      CARD16	height);
128
129
static void	    rfbSpriteGlyphs(CARD8	op,
130
				   PicturePtr	pSrc,
131
				   PicturePtr	pDst,
132
				   PictFormatPtr maskFormat,
133
				   INT16	xSrc,
134
				   INT16	ySrc,
135
				   int		nlist,
136
				   GlyphListPtr	list,
137
				   GlyphPtr	*glyphs);
138
#endif
139
140
static void	    rfbSpriteSaveDoomedAreas(WindowPtr pWin,
141
					    RegionPtr pObscured, int dx,
142
					    int dy);
143
static RegionPtr    rfbSpriteRestoreAreas(WindowPtr pWin, RegionPtr pRgnExposed);
144
static void	    rfbSpriteComputeSaved(ScreenPtr pScreen);
145
146
#define SCREEN_PROLOGUE(pScreen, field)\
147
  ((pScreen)->field = \
148
   ((rfbSpriteScreenPtr) (pScreen)->devPrivates[rfbSpriteScreenIndex].ptr)->field) 
149
150
#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
151
    ((pScreen)->field = wrapper)
152
153
/*
154
 * GC func wrappers
155
 */
156
157
static int  rfbSpriteGCIndex;
158
159
static void rfbSpriteValidateGC(GCPtr pGC, unsigned long stateChanges,
160
			       DrawablePtr pDrawable);
161
static void rfbSpriteCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
162
static void rfbSpriteDestroyGC(GCPtr pGC);
163
static void rfbSpriteChangeGC(GCPtr pGC, unsigned long mask);
164
static void rfbSpriteChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
165
static void rfbSpriteDestroyClip(GCPtr pGC);
166
static void rfbSpriteCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
167
168
static GCFuncs	rfbSpriteGCFuncs = {
169
    rfbSpriteValidateGC,
170
    rfbSpriteChangeGC,
171
    rfbSpriteCopyGC,
172
    rfbSpriteDestroyGC,
173
    rfbSpriteChangeClip,
174
    rfbSpriteDestroyClip,
175
    rfbSpriteCopyClip,
176
};
177
178
#define GC_FUNC_PROLOGUE(pGC)					\
179
    rfbSpriteGCPtr   pGCPriv =					\
180
	(rfbSpriteGCPtr) (pGC)->devPrivates[rfbSpriteGCIndex].ptr;\
181
    (pGC)->funcs = pGCPriv->wrapFuncs;				\
182
    if (pGCPriv->wrapOps)					\
183
	(pGC)->ops = pGCPriv->wrapOps;
184
185
#define GC_FUNC_EPILOGUE(pGC)					\
186
    pGCPriv->wrapFuncs = (pGC)->funcs;				\
187
    (pGC)->funcs = &rfbSpriteGCFuncs;				\
188
    if (pGCPriv->wrapOps)					\
189
    {								\
190
	pGCPriv->wrapOps = (pGC)->ops;				\
191
	(pGC)->ops = &rfbSpriteGCOps;				\
192
    }
193
194
/*
195
 * GC op wrappers
196
 */
197
198
static void	    rfbSpriteFillSpans(DrawablePtr pDrawable, GCPtr pGC,
199
				      int nInit, DDXPointPtr pptInit,
200
				      int *pwidthInit, int fSorted);
201
static void	    rfbSpriteSetSpans(DrawablePtr pDrawable, GCPtr pGC,
202
				     char *psrc, DDXPointPtr ppt, int *pwidth,
203
				     int nspans, int fSorted);
204
static void	    rfbSpritePutImage(DrawablePtr pDrawable, GCPtr pGC,
205
				     int depth, int x, int y, int w, int h,
206
				     int leftPad, int format, char *pBits);
207
static RegionPtr    rfbSpriteCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
208
				     GCPtr pGC, int srcx, int srcy, int w,
209
				     int h, int dstx, int dsty);
210
static RegionPtr    rfbSpriteCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
211
				     GCPtr pGC, int srcx, int srcy, int w,
212
				     int h, int dstx, int dsty,
213
				     unsigned long plane);
214
static void	    rfbSpritePolyPoint(DrawablePtr pDrawable, GCPtr pGC,
215
				      int mode, int npt, xPoint *pptInit);
216
static void	    rfbSpritePolylines(DrawablePtr pDrawable, GCPtr pGC,
217
				      int mode, int npt, DDXPointPtr pptInit);
218
static void	    rfbSpritePolySegment(DrawablePtr pDrawable, GCPtr pGC,
219
					int nseg, xSegment *pSegs);
220
static void	    rfbSpritePolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
221
					  int nrects, xRectangle *pRects);
222
static void	    rfbSpritePolyArc(DrawablePtr pDrawable, GCPtr pGC,
223
				    int narcs, xArc *parcs);
224
static void	    rfbSpriteFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
225
					int shape, int mode, int count,
226
					DDXPointPtr pPts);
227
static void	    rfbSpritePolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
228
					 int nrectFill, xRectangle *prectInit);
229
static void	    rfbSpritePolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
230
					int narcs, xArc *parcs);
231
static int	    rfbSpritePolyText8(DrawablePtr pDrawable, GCPtr pGC,
232
				      int x, int y, int count, char *chars);
233
static int	    rfbSpritePolyText16(DrawablePtr pDrawable, GCPtr pGC,
234
				       int x, int y, int count,
235
				       unsigned short *chars);
236
static void	    rfbSpriteImageText8(DrawablePtr pDrawable, GCPtr pGC,
237
				       int x, int y, int count, char *chars);
238
static void	    rfbSpriteImageText16(DrawablePtr pDrawable, GCPtr pGC,
239
					int x, int y, int count,
240
					unsigned short *chars);
241
static void	    rfbSpriteImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
242
					  int x, int y, unsigned int nglyph,
243
					  CharInfoPtr *ppci,
244
					  pointer pglyphBase);
245
static void	    rfbSpritePolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
246
					 int x, int y, unsigned int nglyph,
247
					 CharInfoPtr *ppci,
248
					 pointer pglyphBase);
249
static void	    rfbSpritePushPixels(GCPtr pGC, PixmapPtr pBitMap,
250
				       DrawablePtr pDst, int w, int h,
251
				       int x, int y);
252
#ifdef NEED_LINEHELPER
253
static void	    rfbSpriteLineHelper();
254
#endif
255
256
static GCOps rfbSpriteGCOps = {
257
    rfbSpriteFillSpans,	    rfbSpriteSetSpans,	    rfbSpritePutImage,	
258
    rfbSpriteCopyArea,	    rfbSpriteCopyPlane,	    rfbSpritePolyPoint,
259
    rfbSpritePolylines,	    rfbSpritePolySegment,   rfbSpritePolyRectangle,
260
    rfbSpritePolyArc,	    rfbSpriteFillPolygon,   rfbSpritePolyFillRect,
261
    rfbSpritePolyFillArc,   rfbSpritePolyText8,	    rfbSpritePolyText16,
262
    rfbSpriteImageText8,    rfbSpriteImageText16,   rfbSpriteImageGlyphBlt,
263
    rfbSpritePolyGlyphBlt,  rfbSpritePushPixels
264
#ifdef NEED_LINEHELPER
265
    , rfbSpriteLineHelper
266
#endif
267
};
268
269
/*
270
 * testing only -- remove cursor for every draw.  Eventually,
271
 * each draw operation will perform a bounding box check against
272
 * the saved cursor area
273
 */
274
275
#define GC_SETUP_CHEAP(pDrawable)				    \
276
    rfbSpriteScreenPtr	pScreenPriv = (rfbSpriteScreenPtr)	    \
277
	(pDrawable)->pScreen->devPrivates[rfbSpriteScreenIndex].ptr; \
278
279
#define GC_SETUP(pDrawable, pGC)				    \
280
    GC_SETUP_CHEAP(pDrawable)					    \
281
    rfbSpriteGCPtr	pGCPrivate = (rfbSpriteGCPtr)		    \
282
	(pGC)->devPrivates[rfbSpriteGCIndex].ptr;		    \
283
    GCFuncs *oldFuncs = pGC->funcs;
284
285
#define GC_SETUP_AND_CHECK(pDrawable, pGC)			    \
286
    GC_SETUP(pDrawable, pGC);					    \
287
    if (GC_CHECK((WindowPtr)pDrawable))				    \
288
	rfbSpriteRemoveCursor (pDrawable->pScreen);
289
    
290
#define GC_CHECK(pWin)						    \
291
    (pVNC->cursorIsDrawn &&					    \
292
        (pScreenPriv->pCacheWin == pWin ?			    \
293
	    pScreenPriv->isInCacheWin : (			    \
294
	    (pScreenPriv->pCacheWin = (pWin)) ,			    \
295
	    (pScreenPriv->isInCacheWin =			    \
296
		(pWin)->drawable.x < pScreenPriv->saved.x2 &&	    \
297
		pScreenPriv->saved.x1 < (pWin)->drawable.x +	    \
298
				    (int) (pWin)->drawable.width && \
299
		(pWin)->drawable.y < pScreenPriv->saved.y2 &&	    \
300
		pScreenPriv->saved.y1 < (pWin)->drawable.y +	    \
301
				    (int) (pWin)->drawable.height &&\
302
		RECT_IN_REGION((pWin)->drawable.pScreen, &(pWin)->borderClip, \
303
			&pScreenPriv->saved) != rgnOUT))))
304
305
#define GC_OP_PROLOGUE(pGC) { \
306
    (pGC)->funcs = pGCPrivate->wrapFuncs; \
307
    (pGC)->ops = pGCPrivate->wrapOps; \
308
    }
309
310
#define GC_OP_EPILOGUE(pGC) { \
311
    pGCPrivate->wrapOps = (pGC)->ops; \
312
    (pGC)->funcs = oldFuncs; \
313
    (pGC)->ops = &rfbSpriteGCOps; \
314
    }
315
316
/*
317
 * pointer-sprite method table
318
 */
319
320
static Bool rfbSpriteRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor);
321
static Bool rfbSpriteUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor);
322
static void rfbSpriteSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y);
323
static void rfbSpriteMoveCursor (ScreenPtr pScreen, int x, int y);
324
325
miPointerSpriteFuncRec rfbSpritePointerFuncs = {
326
    rfbSpriteRealizeCursor,
327
    rfbSpriteUnrealizeCursor,
328
    rfbSpriteSetCursor,
329
    rfbSpriteMoveCursor,
330
};
331
332
/*
333
 * other misc functions
334
 */
335
336
static Bool rfbDisplayCursor (ScreenPtr pScreen, CursorPtr pCursor);
337
338
339
/*
340
 * rfbSpriteInitialize -- called from device-dependent screen
341
 * initialization proc after all of the function pointers have
342
 * been stored in the screen structure.
343
 */
344
345
Bool
346
rfbSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
347
    ScreenPtr		    pScreen;
348
    rfbSpriteCursorFuncPtr   cursorFuncs;
349
    miPointerScreenFuncPtr  screenFuncs;
350
{
351
    rfbSpriteScreenPtr	pPriv;
352
    VisualPtr		pVisual;
353
#ifdef RENDER
354
    PictureScreenPtr	ps = GetPictureScreenIfSet(pScreen);
355
#endif
356
    
357
    if (rfbSpriteGeneration != serverGeneration)
358
    {
359
	rfbSpriteScreenIndex = AllocateScreenPrivateIndex ();
360
	if (rfbSpriteScreenIndex < 0)
361
	    return FALSE;
362
	rfbSpriteGeneration = serverGeneration;
363
	rfbSpriteGCIndex = AllocateGCPrivateIndex ();
364
    }
365
    if (!AllocateGCPrivate(pScreen, rfbSpriteGCIndex, sizeof(rfbSpriteGCRec)))
366
	return FALSE;
367
    pPriv = (rfbSpriteScreenPtr) xalloc (sizeof (rfbSpriteScreenRec));
368
    if (!pPriv)
369
	return FALSE;
370
    if (!miPointerInitialize (pScreen, &rfbSpritePointerFuncs, screenFuncs,TRUE))
371
    {
372
	xfree ((pointer) pPriv);
373
	return FALSE;
374
    }
375
    for (pVisual = pScreen->visuals;
376
	 pVisual->vid != pScreen->rootVisual;
377
	 pVisual++)
378
	;
379
    pPriv->pVisual = pVisual;
380
    pPriv->CloseScreen = pScreen->CloseScreen;
381
    pPriv->GetImage = pScreen->GetImage;
382
    pPriv->GetSpans = pScreen->GetSpans;
383
    pPriv->SourceValidate = pScreen->SourceValidate;
384
    pPriv->CreateGC = pScreen->CreateGC;
385
#if 0
386
    pPriv->BlockHandler = pScreen->BlockHandler;
387
#endif
388
    pPriv->InstallColormap = pScreen->InstallColormap;
389
    pPriv->StoreColors = pScreen->StoreColors;
390
    pPriv->DisplayCursor = pScreen->DisplayCursor;
391
392
    pPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
393
    pPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
394
    pPriv->CopyWindow = pScreen->CopyWindow;
395
    pPriv->ClearToBackground = pScreen->ClearToBackground;
396
397
    pPriv->SaveDoomedAreas = pScreen->SaveDoomedAreas;
398
    pPriv->RestoreAreas = pScreen->RestoreAreas;
399
#ifdef RENDER
400
    if (ps)
401
    {
402
	pPriv->Composite = ps->Composite;
403
	pPriv->Glyphs = ps->Glyphs;
404
    }
405
#endif
406
407
    pPriv->pCursor = NULL;
408
    pPriv->x = 0;
409
    pPriv->y = 0;
410
    pPriv->shouldBeUp = FALSE;
411
    pPriv->pCacheWin = NullWindow;
412
    pPriv->isInCacheWin = FALSE;
413
    pPriv->checkPixels = TRUE;
414
    pPriv->pInstalledMap = NULL;
415
    pPriv->pColormap = NULL;
416
    pPriv->funcs = cursorFuncs;
417
    pPriv->colors[SOURCE_COLOR].red = 0;
418
    pPriv->colors[SOURCE_COLOR].green = 0;
419
    pPriv->colors[SOURCE_COLOR].blue = 0;
420
    pPriv->colors[MASK_COLOR].red = 0;
421
    pPriv->colors[MASK_COLOR].green = 0;
422
    pPriv->colors[MASK_COLOR].blue = 0;
423
    pScreen->devPrivates[rfbSpriteScreenIndex].ptr = (pointer) pPriv;
424
    pScreen->CloseScreen = rfbSpriteCloseScreen;
425
    pScreen->GetImage = rfbSpriteGetImage;
426
    pScreen->GetSpans = rfbSpriteGetSpans;
427
    pScreen->SourceValidate = rfbSpriteSourceValidate;
428
    pScreen->CreateGC = rfbSpriteCreateGC;
429
#if 0
430
    pScreen->BlockHandler = rfbSpriteBlockHandler;
431
#endif
432
    pScreen->InstallColormap = rfbSpriteInstallColormap;
433
    pScreen->StoreColors = rfbSpriteStoreColors;
434
435
    pScreen->PaintWindowBackground = rfbSpritePaintWindowBackground;
436
    pScreen->PaintWindowBorder = rfbSpritePaintWindowBorder;
437
    pScreen->CopyWindow = rfbSpriteCopyWindow;
438
    pScreen->ClearToBackground = rfbSpriteClearToBackground;
439
440
    pScreen->SaveDoomedAreas = rfbSpriteSaveDoomedAreas;
441
    pScreen->RestoreAreas = rfbSpriteRestoreAreas;
442
443
    pScreen->DisplayCursor = rfbDisplayCursor;
444
#ifdef RENDER
445
    if (ps)
446
    {
447
	ps->Composite = rfbSpriteComposite;
448
	ps->Glyphs = rfbSpriteGlyphs;
449
    }
450
#endif
451
452
    return TRUE;
453
}
454
455
/*
456
 * Screen wrappers
457
 */
458
459
/*
460
 * CloseScreen wrapper -- unwrap everything, free the private data
461
 * and call the wrapped function
462
 */
463
464
static Bool
465
rfbSpriteCloseScreen (i, pScreen)
466
    ScreenPtr	pScreen;
467
{
468
    rfbSpriteScreenPtr   pScreenPriv;
469
#ifdef RENDER
470
    PictureScreenPtr	ps = GetPictureScreenIfSet(pScreen);
471
#endif
472
473
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
474
475
    pScreen->CloseScreen = pScreenPriv->CloseScreen;
476
    pScreen->GetImage = pScreenPriv->GetImage;
477
    pScreen->GetSpans = pScreenPriv->GetSpans;
478
    pScreen->SourceValidate = pScreenPriv->SourceValidate;
479
    pScreen->CreateGC = pScreenPriv->CreateGC;
480
#if 0
481
    pScreen->BlockHandler = pScreenPriv->BlockHandler;
482
#endif
483
    pScreen->InstallColormap = pScreenPriv->InstallColormap;
484
    pScreen->StoreColors = pScreenPriv->StoreColors;
485
486
    pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground;
487
    pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder;
488
    pScreen->CopyWindow = pScreenPriv->CopyWindow;
489
    pScreen->ClearToBackground = pScreenPriv->ClearToBackground;
490
491
    pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas;
492
    pScreen->RestoreAreas = pScreenPriv->RestoreAreas;
493
#ifdef RENDER
494
    if (ps)
495
    {
496
	ps->Composite = pScreenPriv->Composite;
497
	ps->Glyphs = pScreenPriv->Glyphs;
498
    }
499
#endif
500
501
    xfree ((pointer) pScreenPriv);
502
503
    return (*pScreen->CloseScreen) (i, pScreen);
504
}
505
506
static void
507
rfbSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
508
    DrawablePtr	    pDrawable;
509
    int		    sx, sy, w, h;
510
    unsigned int    format;
511
    unsigned long   planemask;
512
    char	    *pdstLine;
513
{
514
    ScreenPtr	    pScreen = pDrawable->pScreen;
515
    rfbSpriteScreenPtr    pScreenPriv;
516
    VNCSCREENPTR(pScreen);
517
    
518
    SCREEN_PROLOGUE (pScreen, GetImage);
519
520
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
521
522
    if (pDrawable->type == DRAWABLE_WINDOW &&
523
        pVNC->cursorIsDrawn &&
524
	ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h))
525
    {
526
	rfbSpriteRemoveCursor (pScreen);
527
    }
528
529
    (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
530
			  format, planemask, pdstLine);
531
532
    SCREEN_EPILOGUE (pScreen, GetImage, rfbSpriteGetImage);
533
}
534
535
static void
536
rfbSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
537
    DrawablePtr	pDrawable;
538
    int		wMax;
539
    DDXPointPtr	ppt;
540
    int		*pwidth;
541
    int		nspans;
542
    char	*pdstStart;
543
{
544
    ScreenPtr		    pScreen = pDrawable->pScreen;
545
    rfbSpriteScreenPtr	    pScreenPriv;
546
    VNCSCREENPTR(pScreen);
547
    
548
    SCREEN_PROLOGUE (pScreen, GetSpans);
549
550
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
551
552
    if (pDrawable->type == DRAWABLE_WINDOW && pVNC->cursorIsDrawn)
553
    {
554
	register DDXPointPtr    pts;
555
	register int    	*widths;
556
	register int    	nPts;
557
	register int    	xorg,
558
				yorg;
559
560
	xorg = pDrawable->x;
561
	yorg = pDrawable->y;
562
563
	for (pts = ppt, widths = pwidth, nPts = nspans;
564
	     nPts--;
565
	     pts++, widths++)
566
 	{
567
	    if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg,
568
			     pts->x+xorg,*widths))
569
	    {
570
		rfbSpriteRemoveCursor (pScreen);
571
		break;
572
	    }
573
	}
574
    }
575
576
    (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
577
578
    SCREEN_EPILOGUE (pScreen, GetSpans, rfbSpriteGetSpans);
579
}
580
581
static void
582
rfbSpriteSourceValidate (pDrawable, x, y, width, height)
583
    DrawablePtr	pDrawable;
584
    int		x, y, width, height;
585
{
586
    ScreenPtr		    pScreen = pDrawable->pScreen;
587
    rfbSpriteScreenPtr	    pScreenPriv;
588
    VNCSCREENPTR(pScreen);
589
    
590
    SCREEN_PROLOGUE (pScreen, SourceValidate);
591
592
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
593
594
    if (pDrawable->type == DRAWABLE_WINDOW && pVNC->cursorIsDrawn &&
595
	ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y,
596
		    x, y, width, height))
597
    {
598
	rfbSpriteRemoveCursor (pScreen);
599
    }
600
601
    if (pScreen->SourceValidate)
602
	(*pScreen->SourceValidate) (pDrawable, x, y, width, height);
603
604
    SCREEN_EPILOGUE (pScreen, SourceValidate, rfbSpriteSourceValidate);
605
}
606
607
static Bool
608
rfbSpriteCreateGC (pGC)
609
    GCPtr   pGC;
610
{
611
    ScreenPtr	    pScreen = pGC->pScreen;
612
    Bool	    ret;
613
    rfbSpriteGCPtr   pPriv;
614
615
    SCREEN_PROLOGUE (pScreen, CreateGC);
616
    
617
    pPriv = (rfbSpriteGCPtr)pGC->devPrivates[rfbSpriteGCIndex].ptr;
618
619
    ret = (*pScreen->CreateGC) (pGC);
620
621
    pPriv->wrapOps = NULL;
622
    pPriv->wrapFuncs = pGC->funcs;
623
    pGC->funcs = &rfbSpriteGCFuncs;
624
625
    SCREEN_EPILOGUE (pScreen, CreateGC, rfbSpriteCreateGC);
626
627
    return ret;
628
}
629
630
static void
631
rfbSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
632
    int	i;
633
    pointer	blockData;
634
    pointer	pTimeout;
635
    pointer	pReadmask;
636
{
637
    ScreenPtr		pScreen = screenInfo.screens[i];
638
    rfbSpriteScreenPtr	pPriv;
639
    VNCSCREENPTR(pScreen);
640
641
    pPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
642
643
    SCREEN_PROLOGUE(pScreen, BlockHandler);
644
    
645
    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
646
647
    SCREEN_EPILOGUE(pScreen, BlockHandler, rfbSpriteBlockHandler);
648
649
    if (!pVNC->cursorIsDrawn && pPriv->shouldBeUp)
650
	rfbSpriteRestoreCursor (pScreen);
651
}
652
653
static void
654
rfbSpriteInstallColormap (pMap)
655
    ColormapPtr	pMap;
656
{
657
    ScreenPtr		pScreen = pMap->pScreen;
658
    rfbSpriteScreenPtr	pPriv;
659
    VNCSCREENPTR(pScreen);
660
661
    pPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
662
663
    SCREEN_PROLOGUE(pScreen, InstallColormap);
664
    
665
    (*pScreen->InstallColormap) (pMap);
666
667
    SCREEN_EPILOGUE(pScreen, InstallColormap, rfbSpriteInstallColormap);
668
669
    pPriv->pInstalledMap = pMap;
670
    if (pPriv->pColormap != pMap)
671
    {
672
    	pPriv->checkPixels = TRUE;
673
	if (pVNC->cursorIsDrawn)
674
	    rfbSpriteRemoveCursor (pScreen);
675
    }
676
}
677
678
static void
679
rfbSpriteStoreColors (pMap, ndef, pdef)
680
    ColormapPtr	pMap;
681
    int		ndef;
682
    xColorItem	*pdef;
683
{
684
    ScreenPtr		pScreen = pMap->pScreen;
685
    rfbSpriteScreenPtr	pPriv;
686
    int			i;
687
    int			updated;
688
    VisualPtr		pVisual;
689
    VNCSCREENPTR(pScreen);
690
691
    pPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
692
693
    SCREEN_PROLOGUE(pScreen, StoreColors);
694
    
695
    (*pScreen->StoreColors) (pMap, ndef, pdef);
696
697
    SCREEN_EPILOGUE(pScreen, StoreColors, rfbSpriteStoreColors);
698
699
    if (pPriv->pColormap == pMap)
700
    {
701
	updated = 0;
702
	pVisual = pMap->pVisual;
703
	if (pVisual->class == DirectColor)
704
	{
705
	    /* Direct color - match on any of the subfields */
706
707
#define MaskMatch(a,b,mask) ((a) & ((pVisual->mask) == (b)) & (pVisual->mask))
708
709
#define UpdateDAC(plane,dac,mask) {\
710
    if (MaskMatch (pPriv->colors[plane].pixel,pdef[i].pixel,mask)) {\
711
	pPriv->colors[plane].dac = pdef[i].dac; \
712
	updated = 1; \
713
    } \
714
}
715
716
#define CheckDirect(plane) \
717
	    UpdateDAC(plane,red,redMask) \
718
	    UpdateDAC(plane,green,greenMask) \
719
	    UpdateDAC(plane,blue,blueMask)
720
721
	    for (i = 0; i < ndef; i++)
722
	    {
723
		CheckDirect (SOURCE_COLOR)
724
		CheckDirect (MASK_COLOR)
725
	    }
726
	}
727
	else
728
	{
729
	    /* PseudoColor/GrayScale - match on exact pixel */
730
	    for (i = 0; i < ndef; i++)
731
	    {
732
	    	if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel)
733
	    	{
734
		    pPriv->colors[SOURCE_COLOR] = pdef[i];
735
		    if (++updated == 2)
736
		    	break;
737
	    	}
738
	    	if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel)
739
	    	{
740
		    pPriv->colors[MASK_COLOR] = pdef[i];
741
		    if (++updated == 2)
742
		    	break;
743
	    	}
744
	    }
745
	}
746
    	if (updated)
747
    	{
748
	    pPriv->checkPixels = TRUE;
749
	    if (pVNC->cursorIsDrawn)
750
	    	rfbSpriteRemoveCursor (pScreen);
751
    	}
752
    }
753
}
754
755
static void
756
rfbSpriteFindColors (ScreenPtr pScreen)
757
{
758
    rfbSpriteScreenPtr	pScreenPriv = (rfbSpriteScreenPtr)
759
			    pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
760
    CursorPtr		pCursor;
761
    xColorItem		*sourceColor, *maskColor;
762
763
    pCursor = pScreenPriv->pCursor;
764
    sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
765
    maskColor = &pScreenPriv->colors[MASK_COLOR];
766
    if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
767
	!(pCursor->foreRed == sourceColor->red &&
768
	  pCursor->foreGreen == sourceColor->green &&
769
          pCursor->foreBlue == sourceColor->blue &&
770
	  pCursor->backRed == maskColor->red &&
771
	  pCursor->backGreen == maskColor->green &&
772
	  pCursor->backBlue == maskColor->blue))
773
    {
774
	pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
775
	sourceColor->red = pCursor->foreRed;
776
	sourceColor->green = pCursor->foreGreen;
777
	sourceColor->blue = pCursor->foreBlue;
778
	FakeAllocColor (pScreenPriv->pColormap, sourceColor);
779
	maskColor->red = pCursor->backRed;
780
	maskColor->green = pCursor->backGreen;
781
	maskColor->blue = pCursor->backBlue;
782
	FakeAllocColor (pScreenPriv->pColormap, maskColor);
783
	/* "free" the pixels right away, don't let this confuse you */
784
	FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
785
	FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
786
    }
787
    pScreenPriv->checkPixels = FALSE;
788
}
789
790
/*
791
 * BackingStore wrappers
792
 */
793
794
static void
795
rfbSpriteSaveDoomedAreas (pWin, pObscured, dx, dy)
796
    WindowPtr	pWin;
797
    RegionPtr	pObscured;
798
    int		dx, dy;
799
{
800
    ScreenPtr		pScreen = pWin->drawable.pScreen;
801
    rfbSpriteScreenPtr   pScreenPriv;
802
    BoxRec		cursorBox;
803
    VNCSCREENPTR(pScreen);
804
    
805
    SCREEN_PROLOGUE (pScreen, SaveDoomedAreas);
806
807
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
808
    if (pVNC->cursorIsDrawn)
809
    {
810
	cursorBox = pScreenPriv->saved;
811
812
	if (dx || dy)
813
 	{
814
	    cursorBox.x1 += dx;
815
	    cursorBox.y1 += dy;
816
	    cursorBox.x2 += dx;
817
	    cursorBox.y2 += dy;
818
	}
819
	if (RECT_IN_REGION( pScreen, pObscured, &cursorBox) != rgnOUT)
820
	    rfbSpriteRemoveCursor (pScreen);
821
    }
822
823
    (*pScreen->SaveDoomedAreas) (pWin, pObscured, dx, dy);
824
825
    SCREEN_EPILOGUE (pScreen, SaveDoomedAreas, rfbSpriteSaveDoomedAreas);
826
}
827
828
static RegionPtr
829
rfbSpriteRestoreAreas (pWin, prgnExposed)
830
    WindowPtr	pWin;
831
    RegionPtr	prgnExposed;
832
{
833
    ScreenPtr		pScreen = pWin->drawable.pScreen;
834
    rfbSpriteScreenPtr   pScreenPriv;
835
    RegionPtr		result;
836
    VNCSCREENPTR(pScreen);
837
838
    SCREEN_PROLOGUE (pScreen, RestoreAreas);
839
840
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
841
    if (pVNC->cursorIsDrawn)
842
    {
843
	if (RECT_IN_REGION( pScreen, prgnExposed, &pScreenPriv->saved) != rgnOUT)
844
	    rfbSpriteRemoveCursor (pScreen);
845
    }
846
847
    result = (*pScreen->RestoreAreas) (pWin, prgnExposed);
848
849
    SCREEN_EPILOGUE (pScreen, RestoreAreas, rfbSpriteRestoreAreas);
850
851
    return result;
852
}
853
854
/*
855
 * Window wrappers
856
 */
857
858
static void
859
rfbSpritePaintWindowBackground (pWin, pRegion, what)
860
    WindowPtr	pWin;
861
    RegionPtr	pRegion;
862
    int		what;
863
{
864
    ScreenPtr	    pScreen = pWin->drawable.pScreen;
865
    rfbSpriteScreenPtr    pScreenPriv;
866
    VNCSCREENPTR(pScreen);
867
868
    SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
869
870
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
871
    if (pVNC->cursorIsDrawn)
872
    {
873
	/*
874
	 * If the cursor is on the same screen as the window, check the
875
	 * region to paint for the cursor and remove it as necessary
876
	 */
877
	if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT)
878
	    rfbSpriteRemoveCursor (pScreen);
879
    }
880
881
    (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
882
883
    SCREEN_EPILOGUE (pScreen, PaintWindowBackground, rfbSpritePaintWindowBackground);
884
}
885
886
static void
887
rfbSpritePaintWindowBorder (pWin, pRegion, what)
888
    WindowPtr	pWin;
889
    RegionPtr	pRegion;
890
    int		what;
891
{
892
    ScreenPtr	    pScreen = pWin->drawable.pScreen;
893
    rfbSpriteScreenPtr    pScreenPriv;
894
    VNCSCREENPTR(pScreen);
895
896
    SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
897
898
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
899
    if (pVNC->cursorIsDrawn)
900
    {
901
	/*
902
	 * If the cursor is on the same screen as the window, check the
903
	 * region to paint for the cursor and remove it as necessary
904
	 */
905
	if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT)
906
	    rfbSpriteRemoveCursor (pScreen);
907
    }
908
909
    (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
910
911
    SCREEN_EPILOGUE (pScreen, PaintWindowBorder, rfbSpritePaintWindowBorder);
912
}
913
914
static void
915
rfbSpriteCopyWindow (pWin, ptOldOrg, pRegion)
916
    WindowPtr	pWin;
917
    DDXPointRec	ptOldOrg;
918
    RegionPtr	pRegion;
919
{
920
    ScreenPtr	    pScreen = pWin->drawable.pScreen;
921
    rfbSpriteScreenPtr    pScreenPriv;
922
    BoxRec	    cursorBox;
923
    int		    dx, dy;
924
    VNCSCREENPTR(pScreen);
925
926
    SCREEN_PROLOGUE (pScreen, CopyWindow);
927
928
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
929
    if (pVNC->cursorIsDrawn)
930
    {
931
	/*
932
	 * check both the source and the destination areas.  The given
933
	 * region is source relative, so offset the cursor box by
934
	 * the delta position
935
	 */
936
	cursorBox = pScreenPriv->saved;
937
	dx = pWin->drawable.x - ptOldOrg.x;
938
	dy = pWin->drawable.y - ptOldOrg.y;
939
	cursorBox.x1 -= dx;
940
	cursorBox.x2 -= dx;
941
	cursorBox.y1 -= dy;
942
	cursorBox.y2 -= dy;
943
	if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT ||
944
	    RECT_IN_REGION( pScreen, pRegion, &cursorBox) != rgnOUT)
945
	    rfbSpriteRemoveCursor (pScreen);
946
    }
947
948
    (*pScreen->CopyWindow) (pWin, ptOldOrg, pRegion);
949
950
    SCREEN_EPILOGUE (pScreen, CopyWindow, rfbSpriteCopyWindow);
951
}
952
953
static void
954
rfbSpriteClearToBackground (pWin, x, y, w, h, generateExposures)
955
    WindowPtr pWin;
956
    short x,y;
957
    unsigned short w,h;
958
    Bool generateExposures;
959
{
960
    ScreenPtr		pScreen = pWin->drawable.pScreen;
961
    rfbSpriteScreenPtr	pScreenPriv;
962
    int			realw, realh;
963
    VNCSCREENPTR(pScreen);
964
965
    SCREEN_PROLOGUE (pScreen, ClearToBackground);
966
967
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
968
    if (GC_CHECK(pWin))
969
    {
970
	if (!(realw = w))
971
	    realw = (int) pWin->drawable.width - x;
972
	if (!(realh = h))
973
	    realh = (int) pWin->drawable.height - y;
974
	if (ORG_OVERLAP(&pScreenPriv->saved, pWin->drawable.x, pWin->drawable.y,
975
			x, y, realw, realh))
976
	{
977
	    rfbSpriteRemoveCursor (pScreen);
978
	}
979
    }
980
981
    (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
982
983
    SCREEN_EPILOGUE (pScreen, ClearToBackground, rfbSpriteClearToBackground);
984
}
985
986
/*
987
 * GC Func wrappers
988
 */
989
990
static void
991
rfbSpriteValidateGC (pGC, changes, pDrawable)
992
    GCPtr	pGC;
993
    unsigned long	changes;
994
    DrawablePtr	pDrawable;
995
{
996
    GC_FUNC_PROLOGUE (pGC);
997
998
    (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
999
    
1000
    pGCPriv->wrapOps = NULL;
1001
    if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr) pDrawable)->viewable)
1002
    {
1003
	WindowPtr   pWin;
1004
	RegionPtr   pRegion;
1005
1006
	pWin = (WindowPtr) pDrawable;
1007
	pRegion = &pWin->clipList;
1008
	if (pGC->subWindowMode == IncludeInferiors)
1009
	    pRegion = &pWin->borderClip;
1010
	if (REGION_NOTEMPTY(pDrawable->pScreen, pRegion))
1011
	    pGCPriv->wrapOps = pGC->ops;
1012
    }
1013
1014
    GC_FUNC_EPILOGUE (pGC);
1015
}
1016
1017
static void
1018
rfbSpriteChangeGC (pGC, mask)
1019
    GCPtr	    pGC;
1020
    unsigned long   mask;
1021
{
1022
    GC_FUNC_PROLOGUE (pGC);
1023
1024
    (*pGC->funcs->ChangeGC) (pGC, mask);
1025
    
1026
    GC_FUNC_EPILOGUE (pGC);
1027
}
1028
1029
static void
1030
rfbSpriteCopyGC (pGCSrc, mask, pGCDst)
1031
    GCPtr	    pGCSrc, pGCDst;
1032
    unsigned long   mask;
1033
{
1034
    GC_FUNC_PROLOGUE (pGCDst);
1035
1036
    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
1037
    
1038
    GC_FUNC_EPILOGUE (pGCDst);
1039
}
1040
1041
static void
1042
rfbSpriteDestroyGC (pGC)
1043
    GCPtr   pGC;
1044
{
1045
    GC_FUNC_PROLOGUE (pGC);
1046
1047
    (*pGC->funcs->DestroyGC) (pGC);
1048
    
1049
    GC_FUNC_EPILOGUE (pGC);
1050
}
1051
1052
static void
1053
rfbSpriteChangeClip (pGC, type, pvalue, nrects)
1054
    GCPtr   pGC;
1055
    int		type;
1056
    pointer	pvalue;
1057
    int		nrects;
1058
{
1059
    GC_FUNC_PROLOGUE (pGC);
1060
1061
    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
1062
1063
    GC_FUNC_EPILOGUE (pGC);
1064
}
1065
1066
static void
1067
rfbSpriteCopyClip(pgcDst, pgcSrc)
1068
    GCPtr pgcDst, pgcSrc;
1069
{
1070
    GC_FUNC_PROLOGUE (pgcDst);
1071
1072
    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
1073
1074
    GC_FUNC_EPILOGUE (pgcDst);
1075
}
1076
1077
static void
1078
rfbSpriteDestroyClip(pGC)
1079
    GCPtr	pGC;
1080
{
1081
    GC_FUNC_PROLOGUE (pGC);
1082
1083
    (* pGC->funcs->DestroyClip)(pGC);
1084
1085
    GC_FUNC_EPILOGUE (pGC);
1086
}
1087
1088
/*
1089
 * GC Op wrappers
1090
 */
1091
1092
static void
1093
rfbSpriteFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
1094
    DrawablePtr pDrawable;
1095
    GCPtr	pGC;
1096
    int		nInit;			/* number of spans to fill */
1097
    DDXPointPtr pptInit;		/* pointer to list of start points */
1098
    int		*pwidthInit;		/* pointer to list of n widths */
1099
    int 	fSorted;
1100
{
1101
    VNCSCREENPTR(pDrawable->pScreen);
1102
1103
    GC_SETUP(pDrawable, pGC);
1104
1105
    if (GC_CHECK((WindowPtr) pDrawable))
1106
    {
1107
	register DDXPointPtr    pts;
1108
	register int    	*widths;
1109
	register int    	nPts;
1110
1111
	for (pts = pptInit, widths = pwidthInit, nPts = nInit;
1112
	     nPts--;
1113
	     pts++, widths++)
1114
 	{
1115
	     if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths))
1116
	     {
1117
		 rfbSpriteRemoveCursor (pDrawable->pScreen);
1118
		 break;
1119
	     }
1120
	}
1121
    }
1122
1123
    GC_OP_PROLOGUE (pGC);
1124
1125
    (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
1126
1127
    GC_OP_EPILOGUE (pGC);
1128
}
1129
1130
static void
1131
rfbSpriteSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
1132
    DrawablePtr		pDrawable;
1133
    GCPtr		pGC;
1134
    char		*psrc;
1135
    register DDXPointPtr ppt;
1136
    int			*pwidth;
1137
    int			nspans;
1138
    int			fSorted;
1139
{
1140
    VNCSCREENPTR(pDrawable->pScreen);
1141
1142
    GC_SETUP(pDrawable, pGC);
1143
1144
    if (GC_CHECK((WindowPtr) pDrawable))
1145
    {
1146
	register DDXPointPtr    pts;
1147
	register int    	*widths;
1148
	register int    	nPts;
1149
1150
	for (pts = ppt, widths = pwidth, nPts = nspans;
1151
	     nPts--;
1152
	     pts++, widths++)
1153
 	{
1154
	     if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths))
1155
	     {
1156
		 rfbSpriteRemoveCursor(pDrawable->pScreen);
1157
		 break;
1158
	     }
1159
	}
1160
    }
1161
1162
    GC_OP_PROLOGUE (pGC);
1163
1164
    (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
1165
1166
    GC_OP_EPILOGUE (pGC);
1167
}
1168
1169
static void
1170
rfbSpritePutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits)
1171
    DrawablePtr	  pDrawable;
1172
    GCPtr   	  pGC;
1173
    int		  depth;
1174
    int	    	  x;
1175
    int	    	  y;
1176
    int	    	  w;
1177
    int	    	  h;
1178
    int	    	  format;
1179
    char    	  *pBits;
1180
{
1181
    VNCSCREENPTR(pDrawable->pScreen);
1182
1183
    GC_SETUP(pDrawable, pGC);
1184
1185
    if (GC_CHECK((WindowPtr) pDrawable))
1186
    {
1187
	if (ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,
1188
			x,y,w,h))
1189
 	{
1190
	    rfbSpriteRemoveCursor (pDrawable->pScreen);
1191
	}
1192
    }
1193
1194
    GC_OP_PROLOGUE (pGC);
1195
1196
    (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits);
1197
1198
    GC_OP_EPILOGUE (pGC);
1199
}
1200
1201
static RegionPtr
1202
rfbSpriteCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)
1203
    DrawablePtr	  pSrc;
1204
    DrawablePtr	  pDst;
1205
    GCPtr   	  pGC;
1206
    int	    	  srcx;
1207
    int	    	  srcy;
1208
    int	    	  w;
1209
    int	    	  h;
1210
    int	    	  dstx;
1211
    int	    	  dsty;
1212
{
1213
    RegionPtr rgn;
1214
    VNCSCREENPTR(pGC->pScreen);
1215
1216
    GC_SETUP(pDst, pGC);
1217
1218
    /* check destination/source overlap. */
1219
    if (GC_CHECK((WindowPtr) pDst) &&
1220
	 (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) ||
1221
	  ((pDst == pSrc) &&
1222
	   ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h))))
1223
    {
1224
	rfbSpriteRemoveCursor (pDst->pScreen);
1225
    }
1226
 
1227
    GC_OP_PROLOGUE (pGC);
1228
1229
    rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h,
1230
				 dstx, dsty);
1231
1232
    GC_OP_EPILOGUE (pGC);
1233
1234
    return rgn;
1235
}
1236
1237
static RegionPtr
1238
rfbSpriteCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
1239
    DrawablePtr	  pSrc;
1240
    DrawablePtr	  pDst;
1241
    register GCPtr pGC;
1242
    int     	  srcx,
1243
		  srcy;
1244
    int     	  w,
1245
		  h;
1246
    int     	  dstx,
1247
		  dsty;
1248
    unsigned long  plane;
1249
{
1250
    RegionPtr rgn;
1251
    VNCSCREENPTR(pGC->pScreen);
1252
1253
    GC_SETUP(pDst, pGC);
1254
1255
    /*
1256
     * check destination/source for overlap.
1257
     */
1258
    if (GC_CHECK((WindowPtr) pDst) &&
1259
	(ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) ||
1260
	 ((pDst == pSrc) &&
1261
	  ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h))))
1262
    {
1263
	rfbSpriteRemoveCursor (pDst->pScreen);
1264
    }
1265
1266
    GC_OP_PROLOGUE (pGC);
1267
1268
    rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
1269
				  dstx, dsty, plane);
1270
1271
    GC_OP_EPILOGUE (pGC);
1272
1273
    return rgn;
1274
}
1275
1276
static void
1277
rfbSpritePolyPoint (pDrawable, pGC, mode, npt, pptInit)
1278
    DrawablePtr pDrawable;
1279
    GCPtr	pGC;
1280
    int		mode;		/* Origin or Previous */
1281
    int		npt;
1282
    xPoint 	*pptInit;
1283
{
1284
    xPoint	t;
1285
    int		n;
1286
    BoxRec	cursor;
1287
    register xPoint *pts;
1288
    VNCSCREENPTR(pDrawable->pScreen);
1289
1290
    GC_SETUP (pDrawable, pGC);
1291
1292
    if (npt && GC_CHECK((WindowPtr) pDrawable))
1293
    {
1294
	cursor.x1 = pScreenPriv->saved.x1 - pDrawable->x;
1295
	cursor.y1 = pScreenPriv->saved.y1 - pDrawable->y;
1296
	cursor.x2 = pScreenPriv->saved.x2 - pDrawable->x;
1297
	cursor.y2 = pScreenPriv->saved.y2 - pDrawable->y;
1298
1299
	if (mode == CoordModePrevious)
1300
	{
1301
	    t.x = 0;
1302
	    t.y = 0;
1303
	    for (pts = pptInit, n = npt; n--; pts++)
1304
	    {
1305
		t.x += pts->x;
1306
		t.y += pts->y;
1307
		if (cursor.x1 <= t.x && t.x <= cursor.x2 &&
1308
		    cursor.y1 <= t.y && t.y <= cursor.y2)
1309
		{
1310
		    rfbSpriteRemoveCursor (pDrawable->pScreen);
1311
		    break;
1312
		}
1313
	    }
1314
	}
1315
	else
1316
	{
1317
	    for (pts = pptInit, n = npt; n--; pts++)
1318
	    {
1319
		if (cursor.x1 <= pts->x && pts->x <= cursor.x2 &&
1320
		    cursor.y1 <= pts->y && pts->y <= cursor.y2)
1321
		{
1322
		    rfbSpriteRemoveCursor (pDrawable->pScreen);
1323
		    break;
1324
		}
1325
	    }
1326
	}
1327
    }
1328
1329
    GC_OP_PROLOGUE (pGC);
1330
1331
    (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit);
1332
1333
    GC_OP_EPILOGUE (pGC);
1334
}
1335
1336
static void
1337
rfbSpritePolylines (pDrawable, pGC, mode, npt, pptInit)
1338
    DrawablePtr	  pDrawable;
1339
    GCPtr   	  pGC;
1340
    int	    	  mode;
1341
    int	    	  npt;
1342
    DDXPointPtr	  pptInit;
1343
{
1344
    BoxPtr  cursor;
1345
    register DDXPointPtr pts;
1346
    int	    n;
1347
    int	    x, y, x1, y1, x2, y2;
1348
    int	    lw;
1349
    int	    extra;
1350
    VNCSCREENPTR(pDrawable->pScreen);
1351
1352
    GC_SETUP (pDrawable, pGC);
1353
1354
    if (npt && GC_CHECK((WindowPtr) pDrawable))
1355
    {
1356
	cursor = &pScreenPriv->saved;
1357
	lw = pGC->lineWidth;
1358
	x = pptInit->x + pDrawable->x;
1359
	y = pptInit->y + pDrawable->y;
1360
1361
	if (npt == 1)
1362
	{
1363
	    extra = lw >> 1;
1364
	    if (LINE_OVERLAP(cursor, x, y, x, y, extra))
1365
		rfbSpriteRemoveCursor (pDrawable->pScreen);
1366
	}
1367
	else
1368
	{
1369
	    extra = lw >> 1;
1370
	    /*
1371
	     * mitered joins can project quite a way from
1372
	     * the line end; the 11 degree miter limit limits
1373
	     * this extension to 10.43 * lw / 2, rounded up
1374
	     * and converted to int yields 6 * lw
1375
	     */
1376
	    if (pGC->joinStyle == JoinMiter)
1377
		extra = 6 * lw;
1378
	    else if (pGC->capStyle == CapProjecting)
1379
		extra = lw;
1380
	    for (pts = pptInit + 1, n = npt - 1; n--; pts++)
1381
	    {
1382
		x1 = x;
1383
		y1 = y;
1384
		if (mode == CoordModeOrigin)
1385
		{
1386
		    x2 = pDrawable->x + pts->x;
1387
		    y2 = pDrawable->y + pts->y;
1388
		}
1389
		else
1390
		{
1391
		    x2 = x + pts->x;
1392
		    y2 = y + pts->y;
1393
		}
1394
		x = x2;
1395
		y = y2;
1396
		LINE_SORT(x1, y1, x2, y2);
1397
		if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra))
1398
		{
1399
		    rfbSpriteRemoveCursor (pDrawable->pScreen);
1400
		    break;
1401
		}
1402
	    }
1403
	}
1404
    }
1405
    GC_OP_PROLOGUE (pGC);
1406
1407
    (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, pptInit);
1408
1409
    GC_OP_EPILOGUE (pGC);
1410
}
1411
1412
static void
1413
rfbSpritePolySegment(pDrawable, pGC, nseg, pSegs)
1414
    DrawablePtr pDrawable;
1415
    GCPtr 	pGC;
1416
    int		nseg;
1417
    xSegment	*pSegs;
1418
{
1419
    int	    n;
1420
    register xSegment *segs;
1421
    BoxPtr  cursor;
1422
    int	    x1, y1, x2, y2;
1423
    int	    extra;
1424
    VNCSCREENPTR(pDrawable->pScreen);
1425
1426
    GC_SETUP(pDrawable, pGC);
1427
1428
    if (nseg && GC_CHECK((WindowPtr) pDrawable))
1429
    {
1430
	cursor = &pScreenPriv->saved;
1431
	extra = pGC->lineWidth >> 1;
1432
	if (pGC->capStyle == CapProjecting)
1433
	    extra = pGC->lineWidth;
1434
	for (segs = pSegs, n = nseg; n--; segs++)
1435
	{
1436
	    x1 = segs->x1 + pDrawable->x;
1437
	    y1 = segs->y1 + pDrawable->y;
1438
	    x2 = segs->x2 + pDrawable->x;
1439
	    y2 = segs->y2 + pDrawable->y;
1440
	    LINE_SORT(x1, y1, x2, y2);
1441
	    if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra))
1442
	    {
1443
		rfbSpriteRemoveCursor (pDrawable->pScreen);
1444
		break;
1445
	    }
1446
	}
1447
    }
1448
1449
    GC_OP_PROLOGUE (pGC);
1450
1451
    (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, pSegs);
1452
1453
    GC_OP_EPILOGUE (pGC);
1454
}
1455
1456
static void
1457
rfbSpritePolyRectangle(pDrawable, pGC, nrects, pRects)
1458
    DrawablePtr	pDrawable;
1459
    GCPtr	pGC;
1460
    int		nrects;
1461
    xRectangle	*pRects;
1462
{
1463
    register xRectangle *rects;
1464
    BoxPtr  cursor;
1465
    int	    lw;
1466
    int	    n;
1467
    int     x1, y1, x2, y2;
1468
    VNCSCREENPTR(pDrawable->pScreen);
1469
    
1470
    GC_SETUP (pDrawable, pGC);
1471
1472
    if (GC_CHECK((WindowPtr) pDrawable))
1473
    {
1474
	lw = pGC->lineWidth >> 1;
1475
	cursor = &pScreenPriv->saved;
1476
	for (rects = pRects, n = nrects; n--; rects++)
1477
	{
1478
	    x1 = rects->x + pDrawable->x;
1479
	    y1 = rects->y + pDrawable->y;
1480
	    x2 = x1 + (int)rects->width;
1481
	    y2 = y1 + (int)rects->height;
1482
	    if (LINE_OVERLAP(cursor, x1, y1, x2, y1, lw) ||
1483
		LINE_OVERLAP(cursor, x2, y1, x2, y2, lw) ||
1484
		LINE_OVERLAP(cursor, x1, y2, x2, y2, lw) ||
1485
		LINE_OVERLAP(cursor, x1, y1, x1, y2, lw))
1486
	    {
1487
		rfbSpriteRemoveCursor (pDrawable->pScreen);
1488
		break;
1489
	    }
1490
	}
1491
    }
1492
1493
    GC_OP_PROLOGUE (pGC);
1494
1495
    (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, pRects);
1496
1497
    GC_OP_EPILOGUE (pGC);
1498
}
1499
1500
static void
1501
rfbSpritePolyArc(pDrawable, pGC, narcs, parcs)
1502
    DrawablePtr	pDrawable;
1503
    register GCPtr	pGC;
1504
    int		narcs;
1505
    xArc	*parcs;
1506
{
1507
    BoxPtr  cursor;
1508
    int	    lw;
1509
    int	    n;
1510
    register xArc *arcs;
1511
    VNCSCREENPTR(pDrawable->pScreen);
1512
    
1513
    GC_SETUP (pDrawable, pGC);
1514
1515
    if (GC_CHECK((WindowPtr) pDrawable))
1516
    {
1517
	lw = pGC->lineWidth >> 1;
1518
	cursor = &pScreenPriv->saved;
1519
	for (arcs = parcs, n = narcs; n--; arcs++)
1520
	{
1521
	    if (ORG_OVERLAP (cursor, pDrawable->x, pDrawable->y,
1522
			     arcs->x - lw, arcs->y - lw,
1523
			     (int) arcs->width + pGC->lineWidth,
1524
 			     (int) arcs->height + pGC->lineWidth))
1525
	    {
1526
		rfbSpriteRemoveCursor (pDrawable->pScreen);
1527
		break;
1528
	    }
1529
	}
1530
    }
1531
1532
    GC_OP_PROLOGUE (pGC);
1533
1534
    (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, parcs);
1535
1536
    GC_OP_EPILOGUE (pGC);
1537
}
1538
1539
static void
1540
rfbSpriteFillPolygon(pDrawable, pGC, shape, mode, count, pPts)
1541
    register DrawablePtr pDrawable;
1542
    register GCPtr	pGC;
1543
    int			shape, mode;
1544
    int			count;
1545
    DDXPointPtr		pPts;
1546
{
1547
    int x, y, minx, miny, maxx, maxy;
1548
    register DDXPointPtr pts;
1549
    int n;
1550
    VNCSCREENPTR(pDrawable->pScreen);
1551
1552
    GC_SETUP (pDrawable, pGC);
1553
1554
    if (count && GC_CHECK((WindowPtr) pDrawable))
1555
    {
1556
	x = pDrawable->x;
1557
	y = pDrawable->y;
1558
	pts = pPts;
1559
	minx = maxx = pts->x;
1560
	miny = maxy = pts->y;
1561
	pts++;
1562
	n = count - 1;
1563
1564
	if (mode == CoordModeOrigin)
1565
	{
1566
	    for (; n--; pts++)
1567
	    {
1568
		if (pts->x < minx)
1569
		    minx = pts->x;
1570
		else if (pts->x > maxx)
1571
		    maxx = pts->x;
1572
		if (pts->y < miny)
1573
		    miny = pts->y;
1574
		else if (pts->y > maxy)
1575
		    maxy = pts->y;
1576
	    }
1577
	    minx += x;
1578
	    miny += y;
1579
	    maxx += x;
1580
	    maxy += y;
1581
	}
1582
	else
1583
	{
1584
	    x += minx;
1585
	    y += miny;
1586
	    minx = maxx = x;
1587
	    miny = maxy = y;
1588
	    for (; n--; pts++)
1589
	    {
1590
		x += pts->x;
1591
		y += pts->y;
1592
		if (x < minx)
1593
		    minx = x;
1594
		else if (x > maxx)
1595
		    maxx = x;
1596
		if (y < miny)
1597
		    miny = y;
1598
		else if (y > maxy)
1599
		    maxy = y;
1600
	    }
1601
	}
1602
	if (BOX_OVERLAP(&pScreenPriv->saved,minx,miny,maxx,maxy))
1603
	    rfbSpriteRemoveCursor (pDrawable->pScreen);
1604
    }
1605
1606
    GC_OP_PROLOGUE (pGC);
1607
1608
    (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pPts);
1609
1610
    GC_OP_EPILOGUE (pGC);
1611
}
1612
1613
static void
1614
rfbSpritePolyFillRect(pDrawable, pGC, nrectFill, prectInit)
1615
    DrawablePtr pDrawable;
1616
    GCPtr	pGC;
1617
    int		nrectFill; 	/* number of rectangles to fill */
1618
    xRectangle	*prectInit;  	/* Pointer to first rectangle to fill */
1619
{
1620
    VNCSCREENPTR(pDrawable->pScreen);
1621
1622
    GC_SETUP(pDrawable, pGC);
1623
1624
    if (GC_CHECK((WindowPtr) pDrawable))
1625
    {
1626
	register int	    nRect;
1627
	register xRectangle *pRect;
1628
	register int	    xorg, yorg;
1629
1630
	xorg = pDrawable->x;
1631
	yorg = pDrawable->y;
1632
1633
	for (nRect = nrectFill, pRect = prectInit; nRect--; pRect++) {
1634
	    if (ORGRECT_OVERLAP(&pScreenPriv->saved,xorg,yorg,pRect)){
1635
		rfbSpriteRemoveCursor(pDrawable->pScreen);
1636
		break;
1637
	    }
1638
	}
1639
    }
1640
1641
    GC_OP_PROLOGUE (pGC);
1642
1643
    (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrectFill, prectInit);
1644
1645
    GC_OP_EPILOGUE (pGC);
1646
}
1647
1648
static void
1649
rfbSpritePolyFillArc(pDrawable, pGC, narcs, parcs)
1650
    DrawablePtr	pDrawable;
1651
    GCPtr	pGC;
1652
    int		narcs;
1653
    xArc	*parcs;
1654
{
1655
    VNCSCREENPTR(pDrawable->pScreen);
1656
1657
    GC_SETUP(pDrawable, pGC);
1658
1659
    if (GC_CHECK((WindowPtr) pDrawable))
1660
    {
1661
	register int	n;
1662
	BoxPtr		cursor;
1663
	register xArc *arcs;
1664
1665
	cursor = &pScreenPriv->saved;
1666
1667
	for (arcs = parcs, n = narcs; n--; arcs++)
1668
	{
1669
	    if (ORG_OVERLAP(cursor, pDrawable->x, pDrawable->y,
1670
			    arcs->x, arcs->y,
1671
 			    (int) arcs->width, (int) arcs->height))
1672
	    {
1673
		rfbSpriteRemoveCursor (pDrawable->pScreen);
1674
		break;
1675
	    }
1676
	}
1677
    }
1678
1679
    GC_OP_PROLOGUE (pGC);
1680
1681
    (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, parcs);
1682
1683
    GC_OP_EPILOGUE (pGC);
1684
}
1685
1686
/*
1687
 * general Poly/Image text function.  Extract glyph information,
1688
 * compute bounding box and remove cursor if it is overlapped.
1689
 */
1690
1691
static Bool
1692
rfbSpriteTextOverlap (DrawablePtr pDraw, FontPtr font, int x, int y, unsigned int n, CharInfoPtr *charinfo, Bool imageblt, unsigned int w, BoxPtr cursorBox)
1693
{
1694
    ExtentInfoRec extents;
1695
1696
    x += pDraw->x;
1697
    y += pDraw->y;
1698
1699
    if (FONTMINBOUNDS(font,characterWidth) >= 0)
1700
    {
1701
	/* compute an approximate (but covering) bounding box */
1702
	if (!imageblt || (charinfo[0]->metrics.leftSideBearing < 0))
1703
	    extents.overallLeft = charinfo[0]->metrics.leftSideBearing;
1704
	else
1705
	    extents.overallLeft = 0;
1706
	if (w)
1707
	    extents.overallRight = w - charinfo[n-1]->metrics.characterWidth;
1708
	else
1709
	    extents.overallRight = FONTMAXBOUNDS(font,characterWidth)
1710
				    * (n - 1);
1711
	if (imageblt && (charinfo[n-1]->metrics.characterWidth >
1712
			 charinfo[n-1]->metrics.rightSideBearing))
1713
	    extents.overallRight += charinfo[n-1]->metrics.characterWidth;
1714
	else
1715
	    extents.overallRight += charinfo[n-1]->metrics.rightSideBearing;
1716
	if (imageblt && FONTASCENT(font) > FONTMAXBOUNDS(font,ascent))
1717
	    extents.overallAscent = FONTASCENT(font);
1718
	else
1719
	    extents.overallAscent = FONTMAXBOUNDS(font, ascent);
1720
	if (imageblt && FONTDESCENT(font) > FONTMAXBOUNDS(font,descent))
1721
	    extents.overallDescent = FONTDESCENT(font);
1722
	else
1723
	    extents.overallDescent = FONTMAXBOUNDS(font,descent);
1724
	if (!BOX_OVERLAP(cursorBox,
1725
			 x + extents.overallLeft,
1726
			 y - extents.overallAscent,
1727
			 x + extents.overallRight,
1728
			 y + extents.overallDescent))
1729
	    return FALSE;
1730
	else if (imageblt && w)
1731
	    return TRUE;
1732
	/* if it does overlap, fall through and compute exactly, because
1733
	 * taking down the cursor is expensive enough to make this worth it
1734
	 */
1735
    }
1736
    QueryGlyphExtents(font, charinfo, n, &extents);
1737
    if (imageblt)
1738
    {
1739
	if (extents.overallWidth > extents.overallRight)
1740
	    extents.overallRight = extents.overallWidth;
1741
	if (extents.overallWidth < extents.overallLeft)
1742
	    extents.overallLeft = extents.overallWidth;
1743
	if (extents.overallLeft > 0)
1744
	    extents.overallLeft = 0;
1745
	if (extents.fontAscent > extents.overallAscent)
1746
	    extents.overallAscent = extents.fontAscent;
1747
	if (extents.fontDescent > extents.overallDescent)
1748
	    extents.overallDescent = extents.fontDescent;
1749
    }
1750
    return (BOX_OVERLAP(cursorBox,
1751
			x + extents.overallLeft,
1752
			y - extents.overallAscent,
1753
			x + extents.overallRight,
1754
			y + extents.overallDescent));
1755
}
1756
1757
/*
1758
 * values for textType:
1759
 */
1760
#define TT_POLY8   0
1761
#define TT_IMAGE8  1
1762
#define TT_POLY16  2
1763
#define TT_IMAGE16 3
1764
1765
static int 
1766
rfbSpriteText (DrawablePtr pDraw, GCPtr pGC, int x, int y, unsigned long count, char *chars, FontEncoding fontEncoding, Bool textType, BoxPtr cursorBox)
1767
{
1768
    CharInfoPtr *charinfo;
1769
    register CharInfoPtr *info;
1770
    unsigned long i;
1771
    unsigned int  n;
1772
    int		  w;
1773
    void   	  (*drawFunc)() = NULL;
1774
1775
    Bool imageblt;
1776
1777
    imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
1778
1779
    charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
1780
    if (!charinfo)
1781
	return x;
1782
1783
    GetGlyphs(pGC->font, count, (unsigned char *)chars,
1784
	      fontEncoding, &i, charinfo);
1785
    n = (unsigned int)i;
1786
    w = 0;
1787
    if (!imageblt)
1788
	for (info = charinfo; i--; info++)
1789
	    w += (*info)->metrics.characterWidth;
1790
1791
    if (n != 0) {
1792
	if (rfbSpriteTextOverlap(pDraw, pGC->font, x, y, n, charinfo, imageblt, w, cursorBox))
1793
	    rfbSpriteRemoveCursor(pDraw->pScreen);
1794
1795
#ifdef AVOID_GLYPHBLT
1796
	/*
1797
	 * On displays like Apollos, which do not optimize the GlyphBlt functions because they
1798
	 * convert fonts to their internal form in RealizeFont and optimize text directly, we
1799
	 * want to invoke the text functions here, not the GlyphBlt functions.
1800
	 */
1801
	switch (textType)
1802
	{
1803
	case TT_POLY8:
1804
	    drawFunc = (void (*)())pGC->ops->PolyText8;
1805
	    break;
1806
	case TT_IMAGE8:
1807
	    drawFunc = pGC->ops->ImageText8;
1808
	    break;
1809
	case TT_POLY16:
1810
	    drawFunc = (void (*)())pGC->ops->PolyText16;
1811
	    break;
1812
	case TT_IMAGE16:
1813
	    drawFunc = pGC->ops->ImageText16;
1814
	    break;
1815
	}
1816
	(*drawFunc) (pDraw, pGC, x, y, (int) count, chars);
1817
#else /* don't AVOID_GLYPHBLT */
1818
	/*
1819
	 * On the other hand, if the device does use GlyphBlt ultimately to do text, we
1820
	 * don't want to slow it down by invoking the text functions and having them call
1821
	 * GetGlyphs all over again, so we go directly to the GlyphBlt functions here.
1822
	 */
1823
	drawFunc = imageblt ? pGC->ops->ImageGlyphBlt : pGC->ops->PolyGlyphBlt;
1824
	(*drawFunc) (pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
1825
#endif /* AVOID_GLYPHBLT */
1826
    }
1827
    DEALLOCATE_LOCAL(charinfo);
1828
    return x + w;
1829
}
1830
1831
static int
1832
rfbSpritePolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars)
1833
{
1834
    int	ret;
1835
    VNCSCREENPTR(pDrawable->pScreen);
1836
1837
    GC_SETUP (pDrawable, pGC);
1838
1839
    GC_OP_PROLOGUE (pGC);
1840
1841
    if (GC_CHECK((WindowPtr) pDrawable))
1842
	ret = rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count, chars,
1843
			    Linear8Bit, TT_POLY8, &pScreenPriv->saved);
1844
    else
1845
	ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
1846
1847
    GC_OP_EPILOGUE (pGC);
1848
    return ret;
1849
}
1850
1851
static int
1852
rfbSpritePolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars)
1853
{
1854
    int	ret;
1855
    VNCSCREENPTR(pDrawable->pScreen);
1856
1857
    GC_SETUP(pDrawable, pGC);
1858
1859
    GC_OP_PROLOGUE (pGC);
1860
1861
    if (GC_CHECK((WindowPtr) pDrawable))
1862
	ret = rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
1863
			    (char *)chars,
1864
			    FONTLASTROW(pGC->font) == 0 ?
1865
			    Linear16Bit : TwoD16Bit, TT_POLY16, &pScreenPriv->saved);
1866
    else
1867
	ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
1868
1869
    GC_OP_EPILOGUE (pGC);
1870
    return ret;
1871
}
1872
1873
static void
1874
rfbSpriteImageText8(pDrawable, pGC, x, y, count, chars)
1875
    DrawablePtr pDrawable;
1876
    GCPtr	pGC;
1877
    int		x, y;
1878
    int		count;
1879
    char	*chars;
1880
{
1881
    VNCSCREENPTR(pDrawable->pScreen);
1882
1883
    GC_SETUP(pDrawable, pGC);
1884
1885
    GC_OP_PROLOGUE (pGC);
1886
1887
    if (GC_CHECK((WindowPtr) pDrawable))
1888
	(void) rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
1889
			     chars, Linear8Bit, TT_IMAGE8, &pScreenPriv->saved);
1890
    else
1891
	(*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
1892
1893
    GC_OP_EPILOGUE (pGC);
1894
}
1895
1896
static void
1897
rfbSpriteImageText16(pDrawable, pGC, x, y, count, chars)
1898
    DrawablePtr pDrawable;
1899
    GCPtr	pGC;
1900
    int		x, y;
1901
    int		count;
1902
    unsigned short *chars;
1903
{
1904
    VNCSCREENPTR(pDrawable->pScreen);
1905
1906
    GC_SETUP(pDrawable, pGC);
1907
1908
    GC_OP_PROLOGUE (pGC);
1909
1910
    if (GC_CHECK((WindowPtr) pDrawable))
1911
	(void) rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
1912
			     (char *)chars,
1913
			    FONTLASTROW(pGC->font) == 0 ?
1914
			    Linear16Bit : TwoD16Bit, TT_IMAGE16, &pScreenPriv->saved);
1915
    else
1916
	(*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
1917
1918
    GC_OP_EPILOGUE (pGC);
1919
}
1920
1921
static void
1922
rfbSpriteImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
1923
    DrawablePtr pDrawable;
1924
    GCPtr 	pGC;
1925
    int 	x, y;
1926
    unsigned int nglyph;
1927
    CharInfoPtr *ppci;		/* array of character info */
1928
    pointer 	pglyphBase;	/* start of array of glyphs */
1929
{
1930
    VNCSCREENPTR(pDrawable->pScreen);
1931
1932
    GC_SETUP(pDrawable, pGC);
1933
1934
    GC_OP_PROLOGUE (pGC);
1935
1936
    if (GC_CHECK((WindowPtr) pDrawable) &&
1937
	rfbSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, TRUE, 0, &pScreenPriv->saved))
1938
    {
1939
	rfbSpriteRemoveCursor(pDrawable->pScreen);
1940
    }
1941
    (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
1942
1943
    GC_OP_EPILOGUE (pGC);
1944
}
1945
1946
static void
1947
rfbSpritePolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
1948
    DrawablePtr pDrawable;
1949
    GCPtr	pGC;
1950
    int 	x, y;
1951
    unsigned int nglyph;
1952
    CharInfoPtr *ppci;		/* array of character info */
1953
    pointer	pglyphBase;	/* start of array of glyphs */
1954
{
1955
    VNCSCREENPTR(pDrawable->pScreen);
1956
1957
    GC_SETUP (pDrawable, pGC);
1958
1959
    GC_OP_PROLOGUE (pGC);
1960
1961
    if (GC_CHECK((WindowPtr) pDrawable) &&
1962
	rfbSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, FALSE, 0, &pScreenPriv->saved))
1963
    {
1964
	rfbSpriteRemoveCursor(pDrawable->pScreen);
1965
    }
1966
    (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
1967
1968
    GC_OP_EPILOGUE (pGC);
1969
}
1970
1971
static void
1972
rfbSpritePushPixels(pGC, pBitMap, pDrawable, w, h, x, y)
1973
    GCPtr	pGC;
1974
    PixmapPtr	pBitMap;
1975
    DrawablePtr pDrawable;
1976
    int		w, h, x, y;
1977
{
1978
    VNCSCREENPTR(pDrawable->pScreen);
1979
    GC_SETUP(pDrawable, pGC);
1980
1981
    if (GC_CHECK((WindowPtr) pDrawable) &&
1982
	ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,x,y,w,h))
1983
    {
1984
	rfbSpriteRemoveCursor (pDrawable->pScreen);
1985
    }
1986
1987
    GC_OP_PROLOGUE (pGC);
1988
1989
    (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y);
1990
1991
    GC_OP_EPILOGUE (pGC);
1992
}
1993
1994
#ifdef NEED_LINEHELPER
1995
/*
1996
 * I don't expect this routine will ever be called, as the GC
1997
 * will have been unwrapped for the line drawing
1998
 */
1999
2000
static void
2001
rfbSpriteLineHelper()
2002
{
2003
    FatalError("rfbSpriteLineHelper called\n");
2004
}
2005
#endif
2006
2007
#ifdef RENDER
2008
2009
# define mod(a,b)	((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
2010
2011
static void
2012
rfbSpritePictureOverlap (PicturePtr  pPict,
2013
			INT16	    x,
2014
			INT16	    y,
2015
			CARD16	    w,
2016
			CARD16	    h)
2017
{
2018
    VNCSCREENPTR(pPict->pDrawable->pScreen);
2019
2020
    if (pPict->pDrawable->type == DRAWABLE_WINDOW)
2021
    {
2022
	WindowPtr		pWin = (WindowPtr) (pPict->pDrawable);
2023
	rfbSpriteScreenPtr	pScreenPriv = (rfbSpriteScreenPtr)
2024
	    pPict->pDrawable->pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2025
	if (GC_CHECK(pWin))
2026
	{
2027
	    if (pPict->repeat)
2028
	    {
2029
		x = mod(x,pWin->drawable.width);
2030
		y = mod(y,pWin->drawable.height);
2031
	    }
2032
	    if (ORG_OVERLAP (&pScreenPriv->saved, pWin->drawable.x, pWin->drawable.y,
2033
			     x, y, w, h))
2034
		rfbSpriteRemoveCursor (pWin->drawable.pScreen);
2035
	}
2036
    }
2037
}
2038
2039
#define PICTURE_PROLOGUE(ps, pScreenPriv, field) \
2040
    ps->field = pScreenPriv->field
2041
2042
#define PICTURE_EPILOGUE(ps, field, wrap) \
2043
    ps->field = wrap
2044
2045
static void
2046
rfbSpriteComposite(CARD8	op,
2047
		  PicturePtr pSrc,
2048
		  PicturePtr pMask,
2049
		  PicturePtr pDst,
2050
		  INT16	xSrc,
2051
		  INT16	ySrc,
2052
		  INT16	xMask,
2053
		  INT16	yMask,
2054
		  INT16	xDst,
2055
		  INT16	yDst,
2056
		  CARD16	width,
2057
		  CARD16	height)
2058
{
2059
    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
2060
    PictureScreenPtr	ps = GetPictureScreen(pScreen);
2061
    rfbSpriteScreenPtr	pScreenPriv;
2062
2063
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2064
    PICTURE_PROLOGUE(ps, pScreenPriv, Composite);
2065
    rfbSpritePictureOverlap (pSrc, xSrc, ySrc, width, height);
2066
    if (pMask)
2067
	rfbSpritePictureOverlap (pMask, xMask, yMask, width, height);
2068
    rfbSpritePictureOverlap (pDst, xDst, yDst, width, height);
2069
2070
    (*ps->Composite) (op,
2071
		       pSrc,
2072
		       pMask,
2073
		       pDst,
2074
		       xSrc,
2075
		       ySrc,
2076
		       xMask,
2077
		       yMask,
2078
		       xDst,
2079
		       yDst,
2080
		       width,
2081
		       height);
2082
    
2083
    PICTURE_EPILOGUE(ps, Composite, rfbSpriteComposite);
2084
}
2085
2086
static void
2087
rfbSpriteGlyphs(CARD8		op,
2088
	       PicturePtr	pSrc,
2089
	       PicturePtr	pDst,
2090
	       PictFormatPtr	maskFormat,
2091
	       INT16		xSrc,
2092
	       INT16		ySrc,
2093
	       int		nlist,
2094
	       GlyphListPtr	list,
2095
	       GlyphPtr		*glyphs)
2096
{
2097
    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
2098
    VNCSCREENPTR(pScreen);
2099
    PictureScreenPtr	ps = GetPictureScreen(pScreen);
2100
    rfbSpriteScreenPtr	pScreenPriv;
2101
2102
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2103
    PICTURE_PROLOGUE(ps, pScreenPriv, Glyphs);
2104
    if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
2105
    {
2106
	WindowPtr   pSrcWin = (WindowPtr) (pSrc->pDrawable);
2107
2108
	if (GC_CHECK(pSrcWin))
2109
	    rfbSpriteRemoveCursor (pScreen);
2110
    }
2111
    if (pDst->pDrawable->type == DRAWABLE_WINDOW)
2112
    {
2113
	WindowPtr   pDstWin = (WindowPtr) (pDst->pDrawable);
2114
2115
	if (GC_CHECK(pDstWin))
2116
	{
2117
	    BoxRec  extents;
2118
2119
	    miGlyphExtents (nlist, list, glyphs, &extents);
2120
	    if (BOX_OVERLAP(&pScreenPriv->saved,
2121
			    extents.x1 + pDstWin->drawable.x,
2122
			    extents.y1 + pDstWin->drawable.y,
2123
			    extents.x2 + pDstWin->drawable.x,
2124
			    extents.y2 + pDstWin->drawable.y))
2125
	    {
2126
		rfbSpriteRemoveCursor (pScreen);
2127
	    }
2128
	}
2129
    }
2130
    
2131
    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
2132
    
2133
    PICTURE_EPILOGUE (ps, Glyphs, rfbSpriteGlyphs);
2134
}
2135
#endif
2136
2137
/*
2138
 * miPointer interface routines
2139
 */
2140
2141
#define SPRITE_PAD 8
2142
2143
static Bool
2144
rfbSpriteRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
2145
{
2146
    rfbSpriteScreenPtr	pScreenPriv;
2147
2148
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2149
    if (pCursor == pScreenPriv->pCursor)
2150
	pScreenPriv->checkPixels = TRUE;
2151
    return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);
2152
}
2153
2154
static Bool
2155
rfbSpriteUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
2156
{
2157
    rfbSpriteScreenPtr	pScreenPriv;
2158
2159
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2160
    return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);
2161
}
2162
2163
static void
2164
rfbSpriteSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
2165
{
2166
    rfbSpriteScreenPtr	pScreenPriv;
2167
    rfbClientPtr cl, nextCl;
2168
    VNCSCREENPTR(pScreen);
2169
2170
    pScreenPriv
2171
	= (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2172
    if (!pCursor)
2173
    {
2174
    	pScreenPriv->shouldBeUp = FALSE;
2175
    	if (pVNC->cursorIsDrawn)
2176
	    rfbSpriteRemoveCursor (pScreen);
2177
	pScreenPriv->pCursor = 0;
2178
	return;
2179
    }
2180
    pScreenPriv->shouldBeUp = TRUE;
2181
    if (pScreenPriv->x == x &&
2182
	pScreenPriv->y == y &&
2183
	pScreenPriv->pCursor == pCursor &&
2184
	!pScreenPriv->checkPixels)
2185
    {
2186
	return;
2187
    }
2188
    pScreenPriv->x = x;
2189
    pScreenPriv->y = y;
2190
    pScreenPriv->pCacheWin = NullWindow;
2191
    if (pScreenPriv->checkPixels || pScreenPriv->pCursor != pCursor)
2192
    {
2193
	pScreenPriv->pCursor = pCursor;
2194
	rfbSpriteFindColors (pScreen);
2195
    }
2196
    if (pVNC->cursorIsDrawn) {
2197
	int	sx, sy;
2198
	/*
2199
	 * check to see if the old saved region
2200
	 * encloses the new sprite, in which case we use
2201
	 * the flicker-free MoveCursor primitive.
2202
	 */
2203
	sx = pScreenPriv->x - (int)pCursor->bits->xhot;
2204
	sy = pScreenPriv->y - (int)pCursor->bits->yhot;
2205
	if (sx + (int) pCursor->bits->width >= pScreenPriv->saved.x1 &&
2206
	    sx < pScreenPriv->saved.x2 &&
2207
	    sy + (int) pCursor->bits->height >= pScreenPriv->saved.y1 &&
2208
	    sy < pScreenPriv->saved.y2 &&
2209
	    (int) pCursor->bits->width + (2 * SPRITE_PAD) ==
2210
		pScreenPriv->saved.x2 - pScreenPriv->saved.x1 &&
2211
	    (int) pCursor->bits->height + (2 * SPRITE_PAD) ==
2212
		pScreenPriv->saved.y2 - pScreenPriv->saved.y1
2213
	    )
2214
	{
2215
	    pVNC->cursorIsDrawn = FALSE;
2216
	    if (!(sx >= pScreenPriv->saved.x1 &&
2217
	      	  sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 &&
2218
	      	  sy >= pScreenPriv->saved.y1 &&
2219
	      	  sy + (int)pCursor->bits->height < pScreenPriv->saved.y2))
2220
	    {
2221
		int oldx1, oldy1, dx, dy;
2222
2223
		oldx1 = pScreenPriv->saved.x1;
2224
		oldy1 = pScreenPriv->saved.y1;
2225
		dx = oldx1 - (sx - SPRITE_PAD);
2226
		dy = oldy1 - (sy - SPRITE_PAD);
2227
		pScreenPriv->saved.x1 -= dx;
2228
		pScreenPriv->saved.y1 -= dy;
2229
		pScreenPriv->saved.x2 -= dx;
2230
		pScreenPriv->saved.y2 -= dy;
2231
		(void) (*pScreenPriv->funcs->ChangeSave) (pScreen,
2232
				pScreenPriv->saved.x1,
2233
 				pScreenPriv->saved.y1,
2234
				pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
2235
				pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
2236
				dx, dy);
2237
	    }
2238
	    (void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor,
2239
				  pScreenPriv->saved.x1,
2240
 				  pScreenPriv->saved.y1,
2241
				  pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
2242
				  pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
2243
				  sx - pScreenPriv->saved.x1,
2244
				  sy - pScreenPriv->saved.y1,
2245
				  pScreenPriv->colors[SOURCE_COLOR].pixel,
2246
				  pScreenPriv->colors[MASK_COLOR].pixel);
2247
	    pVNC->cursorIsDrawn = TRUE;
2248
	}
2249
	else
2250
	{
2251
	    rfbSpriteRemoveCursor (pScreen);
2252
	}
2253
    }
2254
#if 0
2255
    if (!pVNC->cursorIsDrawn && pScreenPriv->pCursor)
2256
	rfbSpriteRestoreCursor (pScreen);
2257
#endif
2258
    if (pVNC->cursorIsDrawn)
2259
	rfbSpriteRemoveCursor (pScreen);
2260
2261
    for (cl = rfbClientHead; cl; cl = nextCl) {
2262
	nextCl = cl->next;
2263
	if (cl->enableCursorPosUpdates) {
2264
	    if (x == cl->cursorX && y == cl->cursorY) {
2265
		cl->cursorWasMoved = FALSE;
2266
		continue;
2267
	    }
2268
	    cl->cursorWasMoved = TRUE;
2269
	}
2270
	if (REGION_NOTEMPTY(pScreen,&cl->requestedRegion)) {
2271
	    /* cursorIsDrawn is guaranteed to be FALSE here, so we definitely
2272
	       want to send a screen update to the client, even if that's only
2273
	       putting up the cursor */
2274
	    rfbSendFramebufferUpdate(pScreen, cl);
2275
	}
2276
    }
2277
}
2278
2279
static void
2280
rfbSpriteMoveCursor (ScreenPtr pScreen, int x, int y)
2281
{
2282
    rfbSpriteScreenPtr	pScreenPriv;
2283
2284
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2285
    rfbSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y);
2286
}
2287
2288
/*
2289
 * undraw/draw cursor
2290
 */
2291
2292
void
2293
rfbSpriteRemoveCursor (pScreen)
2294
    ScreenPtr	pScreen;
2295
{
2296
    rfbSpriteScreenPtr   pScreenPriv;
2297
    VNCSCREENPTR(pScreen);
2298
2299
    if (!pVNC->cursorIsDrawn)
2300
	return;
2301
2302
    pScreenPriv
2303
	= (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2304
2305
    pVNC->dontSendFramebufferUpdate = TRUE;
2306
    pVNC->cursorIsDrawn = FALSE;
2307
    pScreenPriv->pCacheWin = NullWindow;
2308
    if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen,
2309
					 pScreenPriv->saved.x1,
2310
					 pScreenPriv->saved.y1,
2311
					 pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
2312
					 pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
2313
    {
2314
	pVNC->cursorIsDrawn = TRUE;
2315
    }
2316
    pVNC->dontSendFramebufferUpdate = FALSE;
2317
}
2318
2319
2320
void
2321
rfbSpriteRestoreCursor (pScreen)
2322
    ScreenPtr	pScreen;
2323
{
2324
    rfbSpriteScreenPtr   pScreenPriv;
2325
    int			x, y;
2326
    CursorPtr		pCursor;
2327
    VNCSCREENPTR(pScreen);
2328
2329
    pScreenPriv
2330
	= (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2331
    pCursor = pScreenPriv->pCursor;
2332
2333
    if (pVNC->cursorIsDrawn || !pCursor)
2334
	return;
2335
2336
    pVNC->dontSendFramebufferUpdate = TRUE;
2337
2338
    rfbSpriteComputeSaved (pScreen);
2339
2340
    x = pScreenPriv->x - (int)pCursor->bits->xhot;
2341
    y = pScreenPriv->y - (int)pCursor->bits->yhot;
2342
    if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen,
2343
				      pScreenPriv->saved.x1,
2344
				      pScreenPriv->saved.y1,
2345
				      pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
2346
				      pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
2347
    {
2348
	if (pScreenPriv->checkPixels)
2349
	    rfbSpriteFindColors (pScreen);
2350
	if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y,
2351
				  pScreenPriv->colors[SOURCE_COLOR].pixel,
2352
				  pScreenPriv->colors[MASK_COLOR].pixel))
2353
	    pVNC->cursorIsDrawn = TRUE;
2354
    }
2355
2356
    pVNC->dontSendFramebufferUpdate = FALSE;
2357
}
2358
2359
/*
2360
 * compute the desired area of the screen to save
2361
 */
2362
2363
static void
2364
rfbSpriteComputeSaved (pScreen)
2365
    ScreenPtr	pScreen;
2366
{
2367
    rfbSpriteScreenPtr   pScreenPriv;
2368
    int		    x, y, w, h;
2369
    int		    wpad, hpad;
2370
    CursorPtr	    pCursor;
2371
2372
    pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2373
    pCursor = pScreenPriv->pCursor;
2374
    x = pScreenPriv->x - (int)pCursor->bits->xhot;
2375
    y = pScreenPriv->y - (int)pCursor->bits->yhot;
2376
    w = pCursor->bits->width;
2377
    h = pCursor->bits->height;
2378
    wpad = SPRITE_PAD;
2379
    hpad = SPRITE_PAD;
2380
    pScreenPriv->saved.x1 = x - wpad;
2381
    pScreenPriv->saved.y1 = y - hpad;
2382
    pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2;
2383
    pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2;
2384
}
2385
2386
2387
/*
2388
 * this function is called when the cursor shape is being changed
2389
 */
2390
2391
static Bool
2392
rfbDisplayCursor(pScreen, pCursor)
2393
    ScreenPtr pScreen;
2394
    CursorPtr pCursor;
2395
{
2396
    rfbClientPtr cl;
2397
    rfbSpriteScreenPtr pPriv;
2398
    Bool status;
2399
2400
    for (cl = rfbClientHead; cl ; cl = cl->next) {
2401
	if (cl->enableCursorShapeUpdates)
2402
	    cl->cursorWasChanged = TRUE;
2403
    }
2404
2405
    pPriv = (rfbSpriteScreenPtr)pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2406
    status = (*pPriv->DisplayCursor)(pScreen, pCursor);
2407
2408
    /* send new cursor shape to interested viewers */
2409
    for (cl = rfbClientHead; cl ; cl = cl->next) {
2410
        if (cl->cursorWasChanged) {
2411
            rfbSendFramebufferUpdate(pScreen, cl);
2412
        }
2413
    }
2414
2415
    return status;
2416
}
2417
2418
2419
/*
2420
 * obtain current cursor pointer
2421
 */
2422
2423
CursorPtr
2424
rfbSpriteGetCursorPtr (pScreen)
2425
    ScreenPtr pScreen;
2426
{
2427
    rfbSpriteScreenPtr pScreenPriv;
2428
2429
    pScreenPriv = (rfbSpriteScreenPtr)
2430
	pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2431
2432
    return pScreenPriv->pCursor;
2433
}
2434
2435
/*
2436
 * obtain current cursor position
2437
 */
2438
2439
void
2440
rfbSpriteGetCursorPos (pScreen, px, py)
2441
    ScreenPtr pScreen;
2442
    int *px, *py;
2443
{
2444
    rfbSpriteScreenPtr pScreenPriv;
2445
2446
    pScreenPriv = (rfbSpriteScreenPtr)
2447
	pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2448
2449
    *px = pScreenPriv->x;
2450
    *py = pScreenPriv->y;
2451
}
2452
(-)xorg-server-1.4.orig/hw/vnc/sprite.h (+141 lines)
Line 0 Link Here
1
/*
2
 * sprite.h
3
 *
4
 * software-sprite/sprite drawing - based on misprite
5
 *
6
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
7
 */
8
9
/*
10
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
11
 *
12
 *  This is free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 2 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  This software is distributed in the hope that it will be useful,
18
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 *  GNU General Public License for more details.
21
 *
22
 *  You should have received a copy of the GNU General Public License
23
 *  along with this software; if not, write to the Free Software
24
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
25
 *  USA.
26
 */
27
28
/*
29
30
Copyright (c) 1989  X Consortium
31
32
Permission is hereby granted, free of charge, to any person obtaining a copy
33
of this software and associated documentation files (the "Software"), to deal
34
in the Software without restriction, including without limitation the rights
35
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
copies of the Software, and to permit persons to whom the Software is
37
furnished to do so, subject to the following conditions:
38
39
The above copyright notice and this permission notice shall be included in
40
all copies or substantial portions of the Software.
41
42
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
45
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
46
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
47
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48
49
Except as contained in this notice, the name of the X Consortium shall not be
50
used in advertising or otherwise to promote the sale, use or other dealings
51
in this Software without prior written authorization from the X Consortium.
52
*/
53
54
typedef struct {
55
    Bool	(*RealizeCursor)(
56
		ScreenPtr /*pScreen*/,
57
		CursorPtr /*pCursor*/
58
);
59
    Bool	(*UnrealizeCursor)(
60
		ScreenPtr /*pScreen*/,
61
		CursorPtr /*pCursor*/
62
);
63
    Bool	(*PutUpCursor)(
64
		ScreenPtr /*pScreen*/,
65
		CursorPtr /*pCursor*/,
66
		int /*x*/,
67
		int /*y*/,
68
		unsigned long /*source*/,
69
		unsigned long /*mask*/
70
);
71
    Bool	(*SaveUnderCursor)(
72
		ScreenPtr /*pScreen*/,
73
		int /*x*/,
74
		int /*y*/,
75
		int /*w*/,
76
		int /*h*/
77
);
78
    Bool	(*RestoreUnderCursor)(
79
		ScreenPtr /*pScreen*/,
80
		int /*x*/,
81
		int /*y*/,
82
		int /*w*/,
83
		int /*h*/
84
);
85
    Bool	(*MoveCursor)(
86
		ScreenPtr /*pScreen*/,
87
		CursorPtr /*pCursor*/,
88
		int /*x*/,
89
		int /*y*/,
90
		int /*w*/,
91
		int /*h*/,
92
		int /*dx*/,
93
		int /*dy*/,
94
		unsigned long /*source*/,
95
		unsigned long /*mask*/
96
);
97
    Bool	(*ChangeSave)(
98
		ScreenPtr /*pScreen*/,
99
		int /*x*/,
100
		int /*y*/,
101
		int /*w*/,
102
		int /*h*/,
103
		int /*dx*/,
104
		int /*dy*/
105
);
106
107
} rfbSpriteCursorFuncRec, *rfbSpriteCursorFuncPtr;
108
109
extern Bool rfbSpriteInitialize(
110
#if NeedFunctionPrototypes
111
    ScreenPtr /*pScreen*/,
112
    rfbSpriteCursorFuncPtr /*cursorFuncs*/,
113
    miPointerScreenFuncPtr /*screenFuncs*/
114
#endif
115
);
116
117
extern void rfbSpriteRestoreCursor(
118
#if NeedFunctionPrototypes
119
    ScreenPtr	/*pScreen*/
120
#endif
121
);
122
123
extern void rfbSpriteRemoveCursor(
124
#if NeedFunctionPrototypes
125
    ScreenPtr	/*pScreen*/
126
#endif
127
);
128
129
extern CursorPtr rfbSpriteGetCursorPtr(
130
#if NeedFunctionPrototypes
131
    ScreenPtr	/*pScreen*/
132
#endif
133
);
134
135
extern void rfbSpriteGetCursorPos(
136
#if NeedFunctionPrototypes
137
    ScreenPtr	/*pScreen*/,
138
    int *       /*px*/,
139
    int *       /*py*/
140
#endif
141
);
(-)xorg-server-1.4.orig/hw/vnc/spritest.h (+138 lines)
Line 0 Link Here
1
/*
2
 * spritest.h
3
 *
4
 * sprite structures - based on misprite
5
 *
6
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
7
 */
8
9
/*
10
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
11
 *
12
 *  This is free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 2 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  This software is distributed in the hope that it will be useful,
18
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 *  GNU General Public License for more details.
21
 *
22
 *  You should have received a copy of the GNU General Public License
23
 *  along with this software; if not, write to the Free Software
24
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
25
 *  USA.
26
 */
27
28
/*
29
30
Copyright (c) 1989  X Consortium
31
32
Permission is hereby granted, free of charge, to any person obtaining a copy
33
of this software and associated documentation files (the "Software"), to deal
34
in the Software without restriction, including without limitation the rights
35
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
copies of the Software, and to permit persons to whom the Software is
37
furnished to do so, subject to the following conditions:
38
39
The above copyright notice and this permission notice shall be included in
40
all copies or substantial portions of the Software.
41
42
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
45
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
46
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
47
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48
49
Except as contained in this notice, the name of the X Consortium shall not be
50
used in advertising or otherwise to promote the sale, use or other dealings
51
in this Software without prior written authorization from the X Consortium.
52
*/
53
54
# include   "sprite.h"
55
56
#ifdef RENDER
57
# include   "picturestr.h"
58
#endif
59
60
/*
61
 * per screen information
62
 */
63
64
typedef struct {
65
    CloseScreenProcPtr			CloseScreen;
66
    GetImageProcPtr			GetImage;
67
    GetSpansProcPtr			GetSpans;
68
    SourceValidateProcPtr		SourceValidate;
69
    CreateGCProcPtr			CreateGC;
70
    ScreenBlockHandlerProcPtr		BlockHandler;
71
    InstallColormapProcPtr		InstallColormap;
72
    StoreColorsProcPtr			StoreColors;
73
    PaintWindowBackgroundProcPtr	PaintWindowBackground;
74
    PaintWindowBorderProcPtr		PaintWindowBorder;
75
    CopyWindowProcPtr			CopyWindow;
76
    ClearToBackgroundProcPtr		ClearToBackground;
77
    SaveDoomedAreasProcPtr		SaveDoomedAreas;
78
    RestoreAreasProcPtr			RestoreAreas;
79
    DisplayCursorProcPtr		DisplayCursor;
80
#ifdef RENDER
81
    CompositeProcPtr			Composite;
82
    GlyphsProcPtr			Glyphs;
83
#endif
84
85
    CursorPtr	    pCursor;
86
    int		    x;
87
    int		    y;
88
    Bool	    shouldBeUp;
89
    BoxRec	    saved;
90
    WindowPtr	    pCacheWin;
91
    Bool	    isInCacheWin;
92
    Bool	    checkPixels;
93
    xColorItem	    colors[2];
94
    ColormapPtr	    pInstalledMap;
95
    ColormapPtr	    pColormap;
96
    VisualPtr	    pVisual;
97
    rfbSpriteCursorFuncPtr    funcs;
98
} rfbSpriteScreenRec, *rfbSpriteScreenPtr;
99
100
#define SOURCE_COLOR	0
101
#define MASK_COLOR	1
102
103
typedef struct {
104
    GCFuncs		*wrapFuncs;
105
    GCOps		*wrapOps;
106
} rfbSpriteGCRec, *rfbSpriteGCPtr;
107
108
/*
109
 * Overlap BoxPtr and Box elements
110
 */
111
#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \
112
 	(((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \
113
	 ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2))
114
115
/*
116
 * Overlap BoxPtr, origins, and rectangle
117
 */
118
#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \
119
    BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h))
120
121
/*
122
 * Overlap BoxPtr, origins and RectPtr
123
 */
124
#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \
125
    ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \
126
		(int)((pRect)->width), (int)((pRect)->height))
127
/*
128
 * Overlap BoxPtr and horizontal span
129
 */
130
#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y))
131
132
#define LINE_SORT(x1,y1,x2,y2) \
133
{ int _t; \
134
  if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \
135
  if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } }
136
137
#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \
138
    BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2))
(-)xorg-server-1.4.orig/hw/vnc/stats.c (+117 lines)
Line 0 Link Here
1
/*
2
 * stats.c
3
 *
4
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
5
 */
6
7
/*
8
 *  Copyright (C) 2002 Constantin Kaplinsky.  All Rights Reserved.
9
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
10
 *
11
 *  This is free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  This software is distributed in the hope that it will be useful,
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *  GNU General Public License for more details.
20
 *
21
 *  You should have received a copy of the GNU General Public License
22
 *  along with this software; if not, write to the Free Software
23
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
24
 *  USA.
25
 */
26
#ifdef HAVE_DIX_CONFIG_H
27
#include <dix-config.h>
28
#endif
29
30
31
#include <stdio.h>
32
#include <stdlib.h>
33
#include "rfb.h"
34
35
static char* encNames[] = {
36
    "raw", "copyRect", "RRE", "[encoding 3]", "CoRRE", "hextile",
37
    "zlib", "tight", "[encoding 8]", "[encoding 9]"
38
};
39
40
41
void
42
rfbResetStats(rfbClientPtr cl)
43
{
44
    int i;
45
    for (i = 0; i < MAX_ENCODINGS; i++) {
46
	cl->rfbBytesSent[i] = 0;
47
	cl->rfbRectanglesSent[i] = 0;
48
    }
49
    cl->rfbLastRectMarkersSent = 0;
50
    cl->rfbLastRectBytesSent = 0;
51
    cl->rfbCursorShapeBytesSent = 0;
52
    cl->rfbCursorShapeUpdatesSent = 0;
53
    cl->rfbCursorPosBytesSent = 0;
54
    cl->rfbCursorPosUpdatesSent = 0;
55
    cl->rfbFramebufferUpdateMessagesSent = 0;
56
    cl->rfbRawBytesEquivalent = 0;
57
    cl->rfbKeyEventsRcvd = 0;
58
    cl->rfbPointerEventsRcvd = 0;
59
}
60
61
void
62
rfbPrintStats(rfbClientPtr cl)
63
{
64
    int i;
65
    int totalRectanglesSent = 0;
66
    int totalBytesSent = 0;
67
68
    rfbLog("Statistics:\n");
69
70
    if ((cl->rfbKeyEventsRcvd != 0) || (cl->rfbPointerEventsRcvd != 0))
71
	rfbLog("  key events received %d, pointer events %d\n",
72
		cl->rfbKeyEventsRcvd, cl->rfbPointerEventsRcvd);
73
74
    for (i = 0; i < MAX_ENCODINGS; i++) {
75
	totalRectanglesSent += cl->rfbRectanglesSent[i];
76
	totalBytesSent += cl->rfbBytesSent[i];
77
    }
78
    totalRectanglesSent += (cl->rfbCursorShapeUpdatesSent +
79
			    cl->rfbCursorPosUpdatesSent +
80
			    cl->rfbLastRectMarkersSent);
81
    totalBytesSent += (cl->rfbCursorShapeBytesSent +
82
		       cl->rfbCursorPosBytesSent +
83
		       cl->rfbLastRectBytesSent);
84
85
    rfbLog("  framebuffer updates %d, rectangles %d, bytes %d\n",
86
	    cl->rfbFramebufferUpdateMessagesSent, totalRectanglesSent,
87
	    totalBytesSent);
88
89
    if (cl->rfbLastRectMarkersSent != 0)
90
	rfbLog("    LastRect markers %d, bytes %d\n",
91
		cl->rfbLastRectMarkersSent, cl->rfbLastRectBytesSent);
92
93
    if (cl->rfbCursorShapeUpdatesSent != 0)
94
	rfbLog("    cursor shape updates %d, bytes %d\n",
95
		cl->rfbCursorShapeUpdatesSent, cl->rfbCursorShapeBytesSent);
96
97
    if (cl->rfbCursorPosUpdatesSent != 0)
98
	rfbLog("    cursor position updates %d, bytes %d\n",
99
	       cl->rfbCursorPosUpdatesSent, cl->rfbCursorPosBytesSent);
100
101
    for (i = 0; i < MAX_ENCODINGS; i++) {
102
	if (cl->rfbRectanglesSent[i] != 0)
103
	    rfbLog("    %s rectangles %d, bytes %d\n",
104
		   encNames[i], cl->rfbRectanglesSent[i], cl->rfbBytesSent[i]);
105
    }
106
107
    if ((totalBytesSent - cl->rfbBytesSent[rfbEncodingCopyRect]) != 0) {
108
	rfbLog("  raw bytes equivalent %d, compression ratio %f\n",
109
		cl->rfbRawBytesEquivalent,
110
		(double)cl->rfbRawBytesEquivalent
111
		/ (double)(totalBytesSent -
112
			   cl->rfbBytesSent[rfbEncodingCopyRect] -
113
			   cl->rfbCursorShapeBytesSent -
114
			   cl->rfbCursorPosBytesSent -
115
			   cl->rfbLastRectBytesSent));
116
    }
117
}
(-)xorg-server-1.4.orig/hw/vnc/symlink-vnc.sh (+198 lines)
Line 0 Link Here
1
#!/bin/sh
2
3
#
4
# A script that symlinks source files from vnc to modular
5
#
6
# Author: Soren Sandmann (sandmann@redhat.com) (original)
7
# adapted for vnc by Alan Hourihane <alanh@fairlite.demon.co.uk>
8
9
#
10
# Things we would like to do
11
#
12
#	- Check that all the relevant files exist
13
#		- AUTHORS, autogen.sh, configure.ac, ...
14
#	- Check that we have actually linked everything
15
#		- if a file doesn't need to be linked, then it needs
16
#		  to be listed as "not-linked"
17
#	- Compute diffs between all the files (shouldn't be necessary)
18
#	- possibly check that files are listet in Makefile.am's
19
#	- Clean target directory of irrelevant files
20
#
21
22
check_destinations () {
23
    # don't do anything - we are relying on the side
24
    # effect of dst_dir
25
    true
26
}
27
28
check_exist() {
29
    # Check whether $1 exists
30
31
    if [ ! -e $1 ] ; then
32
	error "$1 not found"
33
    fi
34
}
35
36
delete_existing() {
37
    # Delete $2
38
39
    rm -f $2
40
}
41
42
link_files() {
43
    # Link $1 to $2
44
45
    if [ ! -e $2 ] ; then
46
	ln -s $1 $2
47
    fi
48
}
49
50
main() {
51
    check_args $1 $2
52
53
    run check_destinations "Creating destination directories"
54
    run check_exist "Checking that the source files exist"
55
    run delete_existing "Deleting existing files"
56
    run link_files "Linking files"
57
}
58
59
## actual symlinking
60
61
symlink_vnc() {
62
	src_dir .
63
	dst_dir .
64
	action d3des.c
65
	action d3des.h
66
	action auth.c
67
	action cmap.c
68
	action corre.c
69
	action cursor.c
70
	action cutpaste.c
71
	action dispcur.c
72
	action draw.c
73
	action hextile.c
74
	action httpd.c
75
	action kbdptr.c
76
	action keyboard.h
77
	action loginauth.c
78
	action rdp.c
79
	action rfb.h
80
	action rfbkeyb.c
81
	action rfbmouse.c
82
	action rfbproto.h
83
	action rfbserver.c
84
	action rre.c
85
	action sockets.c
86
	action sprite.c
87
	action sprite.h
88
	action spritest.h
89
	action stats.c
90
	action tableinitcmtemplate.c
91
	action tableinittctemplate.c
92
	action tabletranstemplate.c
93
	action tight.c
94
	action translate.c
95
	action vncauth.c
96
	action vncauth.h
97
	action vncext.c
98
	action xistubs.c
99
	action zlib.c
100
}
101
102
#########
103
#
104
#    Helper functions
105
#
106
#########
107
108
error() {
109
	echo
110
	echo \ \ \ error:\ \ \ $1
111
	exit 1
112
}
113
114
# printing out what's going on
115
run_module() {
116
    # $1 module
117
    # $2 explanation
118
    echo -n $EXPLANATION for $1 module ...\ 
119
    symlink_$1
120
    echo DONE
121
}
122
123
run() {
124
    # $1 what to do
125
    # $2 explanation
126
127
    ACTION=$1 EXPLANATION=$2 run_module vnc
128
}
129
130
src_dir() {
131
    REAL_SRC_DIR=$SRC_DIR/$1
132
    if [ ! -d $REAL_SRC_DIR ] ; then
133
	error "Source directory $REAL_SRC_DIR does not exist"
134
    fi
135
}
136
137
dst_dir() {
138
    REAL_DST_DIR=$DST_DIR/$1
139
    if [ ! -d $REAL_DST_DIR ] ; then
140
	mkdir -p $REAL_DST_DIR
141
    fi
142
}
143
144
action() {
145
    if [ -z $2 ] ; then
146
	$ACTION	$REAL_SRC_DIR/$1	$REAL_DST_DIR/$1
147
    else
148
	$ACTION	$REAL_SRC_DIR/$1	$REAL_DST_DIR/$2
149
    fi
150
}
151
152
usage() {
153
    echo symlink.sh src-dir dst-dir
154
    echo src-dir: the xc directory of the monolithic source tree
155
    echo dst-dir: the modular source tree containing proto, app, lib, ...
156
}
157
158
# Check commandline args
159
check_args() {
160
    if [ -z $1 ] ; then
161
	echo Missing source dir
162
	usage
163
	exit 1
164
    fi
165
166
    if [ -z $2 ] ; then
167
	echo Missing destination dir
168
	usage
169
	exit 1
170
    fi
171
     
172
    if [ ! -d $1 ] ; then
173
	echo $1 is not a dir
174
	usage
175
	exit 1
176
    fi
177
178
    if [ ! -d $2 ] ; then
179
	echo $2 is not a dir
180
	usage
181
	exit 1
182
    fi
183
184
    if [ $1 = $2 ] ; then
185
	echo source and destination can\'t be the same
186
	usage
187
	exit 1
188
    fi
189
190
    D=`dirname "$relpath"`
191
    B=`basename "$relpath"`
192
    abspath="`cd \"$D\" 2>/dev/null && pwd || echo \"$D\"`/$B"
193
194
    SRC_DIR=`( cd $1 ; pwd )`
195
    DST_DIR=`(cd $2 ; pwd )`
196
}
197
198
main $1 $2
(-)xorg-server-1.4.orig/hw/vnc/tableinitcmtemplate.c (+93 lines)
Line 0 Link Here
1
/*
2
 * tableinitcmtemplate.c - template for initialising lookup tables for
3
 * translation from a colour map to true colour.
4
 *
5
 * This file shouldn't be compiled.  It is included multiple times by
6
 * translate.c, each time with a different definition of the macro OUT.
7
 * For each value of OUT, this file defines a function which allocates an
8
 * appropriately sized lookup table and initialises it.
9
 *
10
 * I know this code isn't nice to read because of all the macros, but
11
 * efficiency is important here.
12
 *
13
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
14
 */
15
16
/*
17
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
18
 *
19
 *  This is free software; you can redistribute it and/or modify
20
 *  it under the terms of the GNU General Public License as published by
21
 *  the Free Software Foundation; either version 2 of the License, or
22
 *  (at your option) any later version.
23
 *
24
 *  This software is distributed in the hope that it will be useful,
25
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
26
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
 *  GNU General Public License for more details.
28
 *
29
 *  You should have received a copy of the GNU General Public License
30
 *  along with this software; if not, write to the Free Software
31
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
32
 *  USA.
33
 */
34
#ifdef HAVE_DIX_CONFIG_H
35
#include <dix-config.h>
36
#endif
37
38
39
#if !defined(OUT)
40
#error "This file shouldn't be compiled."
41
#error "It is included as part of translate.c"
42
#endif
43
44
#define OUT_T CONCAT2E(CARD,OUT)
45
#define SwapOUT(x) CONCAT2E(Swap,OUT(x))
46
#define rfbInitColourMapSingleTableOUT \
47
				CONCAT2E(rfbInitColourMapSingleTable,OUT)
48
49
static void
50
rfbInitColourMapSingleTableOUT (ScreenPtr pScreen, char **table, rfbPixelFormat *in,
51
				rfbPixelFormat *out)
52
{
53
    VNCSCREENPTR(pScreen);
54
    int i, r, g, b;
55
    OUT_T *t;
56
    EntryPtr pent;
57
    int nEntries = 1 << in->bitsPerPixel;
58
59
    if (*table) free(*table);
60
    *table = (char *)malloc(nEntries * sizeof(OUT_T));
61
    t = (OUT_T *)*table;
62
63
#if XFREE86VNC
64
    pent = (EntryPtr)&miInstalledMaps[pScreen->myNum]->red[0];
65
#else
66
    pent = (EntryPtr)&pVNC->rfbInstalledColormap->red[0];
67
#endif
68
69
    for (i = 0; i < nEntries; i++) {
70
	if (pent->fShared) {
71
	    r = pent->co.shco.red->color;
72
	    g = pent->co.shco.green->color;
73
	    b = pent->co.shco.blue->color;
74
	} else {
75
	    r = pent->co.local.red;
76
	    g = pent->co.local.green;
77
	    b = pent->co.local.blue;
78
	}
79
	t[i] = ((((r * out->redMax + 32767) / 65535) << out->redShift) |
80
		(((g * out->greenMax + 32767) / 65535) << out->greenShift) |
81
		(((b * out->blueMax + 32767) / 65535) << out->blueShift));
82
#if (OUT != 8)
83
	if (out->bigEndian != in->bigEndian) {
84
	    t[i] = SwapOUT(t[i]);
85
	}
86
#endif
87
	pent++;
88
    }
89
}
90
91
#undef OUT_T
92
#undef SwapOUT
93
#undef rfbInitColourMapSingleTableOUT
(-)xorg-server-1.4.orig/hw/vnc/tableinittctemplate.c (+146 lines)
Line 0 Link Here
1
/*
2
 * tableinittctemplate.c - template for initialising lookup tables for
3
 * truecolour to truecolour translation.
4
 *
5
 * This file shouldn't be compiled.  It is included multiple times by
6
 * translate.c, each time with a different definition of the macro OUT.
7
 * For each value of OUT, this file defines two functions for initialising
8
 * lookup tables.  One is for truecolour translation using a single lookup
9
 * table, the other is for truecolour translation using three separate
10
 * lookup tables for the red, green and blue values.
11
 *
12
 * I know this code isn't nice to read because of all the macros, but
13
 * efficiency is important here.
14
 *
15
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
16
 */
17
18
/*
19
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
20
 *
21
 *  This is free software; you can redistribute it and/or modify
22
 *  it under the terms of the GNU General Public License as published by
23
 *  the Free Software Foundation; either version 2 of the License, or
24
 *  (at your option) any later version.
25
 *
26
 *  This software is distributed in the hope that it will be useful,
27
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
28
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
 *  GNU General Public License for more details.
30
 *
31
 *  You should have received a copy of the GNU General Public License
32
 *  along with this software; if not, write to the Free Software
33
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
34
 *  USA.
35
 */
36
#ifdef HAVE_DIX_CONFIG_H
37
#include <dix-config.h>
38
#endif
39
40
41
#if !defined(OUT)
42
#error "This file shouldn't be compiled."
43
#error "It is included as part of translate.c"
44
#endif
45
46
#define OUT_T CONCAT2E(CARD,OUT)
47
#define SwapOUT(x) CONCAT2E(Swap,OUT(x))
48
#define rfbInitTrueColourSingleTableOUT \
49
				CONCAT2E(rfbInitTrueColourSingleTable,OUT)
50
#define rfbInitTrueColourRGBTablesOUT CONCAT2E(rfbInitTrueColourRGBTables,OUT)
51
#define rfbInitOneRGBTableOUT CONCAT2E(rfbInitOneRGBTable,OUT)
52
53
static void
54
rfbInitOneRGBTableOUT (OUT_T *table, int inMax, int outMax, int outShift,
55
		       int swap);
56
57
58
/*
59
 * rfbInitTrueColourSingleTable sets up a single lookup table for truecolour
60
 * translation.
61
 */
62
63
static void
64
rfbInitTrueColourSingleTableOUT (ScreenPtr pScreen, char **table, rfbPixelFormat *in,
65
				 rfbPixelFormat *out)
66
{
67
    int i;
68
    int inRed, inGreen, inBlue, outRed, outGreen, outBlue;
69
    OUT_T *t;
70
    int nEntries = 1 << in->bitsPerPixel;
71
72
    if (*table) free(*table);
73
    *table = (char *)malloc(nEntries * sizeof(OUT_T));
74
    t = (OUT_T *)*table;
75
76
    for (i = 0; i < nEntries; i++) {
77
	inRed   = (i >> in->redShift)   & in->redMax;
78
	inGreen = (i >> in->greenShift) & in->greenMax;
79
	inBlue  = (i >> in->blueShift)  & in->blueMax;
80
81
	outRed   = (inRed   * out->redMax   + in->redMax / 2)   / in->redMax;
82
	outGreen = (inGreen * out->greenMax + in->greenMax / 2) / in->greenMax;
83
	outBlue  = (inBlue  * out->blueMax  + in->blueMax / 2)  / in->blueMax;
84
85
	t[i] = ((outRed   << out->redShift)   |
86
		(outGreen << out->greenShift) |
87
		(outBlue  << out->blueShift));
88
#if (OUT != 8)
89
	if (out->bigEndian != in->bigEndian) {
90
	    t[i] = SwapOUT(t[i]);
91
	}
92
#endif
93
    }
94
}
95
96
97
/*
98
 * rfbInitTrueColourRGBTables sets up three separate lookup tables for the
99
 * red, green and blue values.
100
 */
101
102
static void
103
rfbInitTrueColourRGBTablesOUT (ScreenPtr pScreen, char **table, rfbPixelFormat *in,
104
			       rfbPixelFormat *out)
105
{
106
    OUT_T *redTable;
107
    OUT_T *greenTable;
108
    OUT_T *blueTable;
109
110
    if (*table) free(*table);
111
    *table = (char *)malloc((in->redMax + in->greenMax + in->blueMax + 3)
112
			    * sizeof(OUT_T));
113
    redTable = (OUT_T *)*table;
114
    greenTable = redTable + in->redMax + 1;
115
    blueTable = greenTable + in->greenMax + 1;
116
117
    rfbInitOneRGBTableOUT (redTable, in->redMax, out->redMax,
118
			   out->redShift, (out->bigEndian != in->bigEndian));
119
    rfbInitOneRGBTableOUT (greenTable, in->greenMax, out->greenMax,
120
			   out->greenShift, (out->bigEndian != in->bigEndian));
121
    rfbInitOneRGBTableOUT (blueTable, in->blueMax, out->blueMax,
122
			   out->blueShift, (out->bigEndian != in->bigEndian));
123
}
124
125
static void
126
rfbInitOneRGBTableOUT (OUT_T *table, int inMax, int outMax, int outShift,
127
		       int swap)
128
{
129
    int i;
130
    int nEntries = inMax + 1;
131
132
    for (i = 0; i < nEntries; i++) {
133
	table[i] = ((i * outMax + inMax / 2) / inMax) << outShift;
134
#if (OUT != 8)
135
	if (swap) {
136
	    table[i] = SwapOUT(table[i]);
137
	}
138
#endif
139
    }
140
}
141
142
#undef OUT_T
143
#undef SwapOUT
144
#undef rfbInitTrueColourSingleTableOUT
145
#undef rfbInitTrueColourRGBTablesOUT
146
#undef rfbInitOneRGBTableOUT
(-)xorg-server-1.4.orig/hw/vnc/tabletranstemplate.c (+135 lines)
Line 0 Link Here
1
/*
2
 * tabletranstemplate.c - template for translation using lookup tables.
3
 *
4
 * This file shouldn't be compiled.  It is included multiple times by
5
 * translate.c, each time with different definitions of the macros IN and OUT.
6
 *
7
 * For each pair of values IN and OUT, this file defines two functions for
8
 * translating a given rectangle of pixel data.  One uses a single lookup
9
 * table, and the other uses three separate lookup tables for the red, green
10
 * and blue values.
11
 *
12
 * I know this code isn't nice to read because of all the macros, but
13
 * efficiency is important here.
14
 *
15
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
16
 */
17
18
/*
19
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
20
 *
21
 *  This is free software; you can redistribute it and/or modify
22
 *  it under the terms of the GNU General Public License as published by
23
 *  the Free Software Foundation; either version 2 of the License, or
24
 *  (at your option) any later version.
25
 *
26
 *  This software is distributed in the hope that it will be useful,
27
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
28
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
 *  GNU General Public License for more details.
30
 *
31
 *  You should have received a copy of the GNU General Public License
32
 *  along with this software; if not, write to the Free Software
33
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
34
 *  USA.
35
 */
36
#ifdef HAVE_DIX_CONFIG_H
37
#include <dix-config.h>
38
#endif
39
40
41
#if !defined(IN) || !defined(OUT)
42
#error "This file shouldn't be compiled."
43
#error "It is included as part of translate.c"
44
#endif
45
46
#define IN_T CONCAT2E(CARD,IN)
47
#define OUT_T CONCAT2E(CARD,OUT)
48
#define rfbTranslateWithSingleTableINtoOUT \
49
				CONCAT4E(rfbTranslateWithSingleTable,IN,to,OUT)
50
#define rfbTranslateWithRGBTablesINtoOUT \
51
				CONCAT4E(rfbTranslateWithRGBTables,IN,to,OUT)
52
53
/*
54
 * rfbTranslateWithSingleTableINtoOUT translates a rectangle of pixel data
55
 * using a single lookup table.
56
 */
57
58
static void
59
rfbTranslateWithSingleTableINtoOUT (ScreenPtr pScreen, char *table, rfbPixelFormat *in,
60
				    rfbPixelFormat *out,
61
				    unsigned char *optr,
62
				    int bytesBetweenInputLines,
63
				    int width, int height,
64
				    int x, int y)
65
{
66
    IN_T *ip;
67
    OUT_T *op = (OUT_T *)optr;
68
    OUT_T *opLineEnd;
69
    OUT_T *t = (OUT_T *)table;
70
    DrawablePtr pDraw = (DrawablePtr)WindowTable[pScreen->myNum];
71
    int truewidth = PixmapBytePad(width, in->bitsPerPixel);
72
    unsigned char *iptr = malloc(truewidth * height * in->bitsPerPixel / 8);
73
    int ipextra = truewidth - width;
74
    (*pScreen->GetImage)(pDraw, x, y, truewidth, height, ZPixmap, ~0, (char*)iptr);
75
    ip = (IN_T *)iptr;
76
77
    while (height > 0) {
78
	opLineEnd = op + width;
79
80
	while (op < opLineEnd) {
81
	    *(op++) = t[*(ip++)];
82
	}
83
84
	ip += ipextra;
85
	height--;
86
    }
87
    free(iptr);
88
}
89
90
91
/*
92
 * rfbTranslateWithRGBTablesINtoOUT translates a rectangle of pixel data
93
 * using three separate lookup tables for the red, green and blue values.
94
 */
95
96
static void
97
rfbTranslateWithRGBTablesINtoOUT (ScreenPtr pScreen, char *table, rfbPixelFormat *in,
98
				  rfbPixelFormat *out,
99
				  unsigned char *optr,
100
				  int bytesBetweenInputLines,
101
				  int width, int height,
102
				  int x, int y)
103
{
104
    IN_T *ip;
105
    OUT_T *op = (OUT_T *)optr;
106
    OUT_T *opLineEnd;
107
    OUT_T *redTable = (OUT_T *)table;
108
    OUT_T *greenTable = redTable + in->redMax + 1;
109
    OUT_T *blueTable = greenTable + in->greenMax + 1;
110
    DrawablePtr pDraw = (DrawablePtr)WindowTable[pScreen->myNum];
111
    int truewidth = PixmapBytePad(width, in->bitsPerPixel);
112
    unsigned char *iptr = malloc(truewidth * height * in->bitsPerPixel / 8);
113
    int ipextra = truewidth - width;
114
    (*pScreen->GetImage)(pDraw, x, y, truewidth, height, ZPixmap, ~0, (char*)iptr);
115
    ip = (IN_T *)iptr;
116
117
    while (height > 0) {
118
	opLineEnd = op + width;
119
120
	while (op < opLineEnd) {
121
	    *(op++) = (redTable[(*ip >> in->redShift) & in->redMax] |
122
		       greenTable[(*ip >> in->greenShift) & in->greenMax] |
123
		       blueTable[(*ip >> in->blueShift) & in->blueMax]);
124
	    ip++;
125
	}
126
	ip += ipextra;
127
	height--;
128
    }
129
    free(iptr);
130
}
131
132
#undef IN_T
133
#undef OUT_T
134
#undef rfbTranslateWithSingleTableINtoOUT
135
#undef rfbTranslateWithRGBTablesINtoOUT
(-)xorg-server-1.4.orig/hw/vnc/tight.c (+1827 lines)
Line 0 Link Here
1
/*
2
 * tight.c
3
 *
4
 * Routines to implement Tight Encoding
5
 *
6
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
7
 */
8
9
/*
10
 *  Copyright (C) 2000, 2001 Const Kaplinsky.  All Rights Reserved.
11
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
12
 *
13
 *  This is free software; you can redistribute it and/or modify
14
 *  it under the terms of the GNU General Public License as published by
15
 *  the Free Software Foundation; either version 2 of the License, or
16
 *  (at your option) any later version.
17
 *
18
 *  This software is distributed in the hope that it will be useful,
19
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 *  GNU General Public License for more details.
22
 *
23
 *  You should have received a copy of the GNU General Public License
24
 *  along with this software; if not, write to the Free Software
25
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
26
 *  USA.
27
 */
28
#ifdef HAVE_DIX_CONFIG_H
29
#include <dix-config.h>
30
#endif
31
32
33
#include <stdio.h>
34
#include "rfb.h"
35
#include <jpeglib.h>
36
37
38
/* Note: The following constant should not be changed. */
39
#define TIGHT_MIN_TO_COMPRESS 12
40
41
/* The parameters below may be adjusted. */
42
#define MIN_SPLIT_RECT_SIZE     4096
43
#define MIN_SOLID_SUBRECT_SIZE  2048
44
#define MAX_SPLIT_TILE_SIZE       16
45
46
/* May be set to TRUE with "-lazytight" Xvnc option. */
47
Bool rfbTightDisableGradient = FALSE;
48
49
/* This variable is set on every rfbSendRectEncodingTight() call. */
50
static Bool usePixelFormat24;
51
52
53
/* Compression level stuff. The following array contains various
54
   encoder parameters for each of 10 compression levels (0..9).
55
   Last three parameters correspond to JPEG quality levels (0..9). */
56
57
typedef struct TIGHT_CONF_s {
58
    int maxRectSize, maxRectWidth;
59
    int monoMinRectSize, gradientMinRectSize;
60
    int idxZlibLevel, monoZlibLevel, rawZlibLevel, gradientZlibLevel;
61
    int gradientThreshold, gradientThreshold24;
62
    int idxMaxColorsDivisor;
63
    int jpegQuality, jpegThreshold, jpegThreshold24;
64
} TIGHT_CONF;
65
66
static TIGHT_CONF tightConf[10] = {
67
    {   512,   32,   6, 65536, 0, 0, 0, 0,   0,   0,   4,  5, 10000, 23000 },
68
    {  2048,  128,   6, 65536, 1, 1, 1, 0,   0,   0,   8, 10,  8000, 18000 },
69
    {  6144,  256,   8, 65536, 3, 3, 2, 0,   0,   0,  24, 15,  6500, 15000 },
70
    { 10240, 1024,  12, 65536, 5, 5, 3, 0,   0,   0,  32, 25,  5000, 12000 },
71
    { 16384, 2048,  12, 65536, 6, 6, 4, 0,   0,   0,  32, 37,  4000, 10000 },
72
    { 32768, 2048,  12,  4096, 7, 7, 5, 4, 150, 380,  32, 50,  3000,  8000 },
73
    { 65536, 2048,  16,  4096, 7, 7, 6, 4, 170, 420,  48, 60,  2000,  5000 },
74
    { 65536, 2048,  16,  4096, 8, 8, 7, 5, 180, 450,  64, 70,  1000,  2500 },
75
    { 65536, 2048,  32,  8192, 9, 9, 8, 6, 190, 475,  64, 75,   500,  1200 },
76
    { 65536, 2048,  32,  8192, 9, 9, 9, 6, 200, 500,  96, 80,   200,   500 }
77
};
78
79
/* Stuff dealing with palettes. */
80
81
typedef struct COLOR_LIST_s {
82
    struct COLOR_LIST_s *next;
83
    int idx;
84
    CARD32 rgb;
85
} COLOR_LIST;
86
87
typedef struct PALETTE_ENTRY_s {
88
    COLOR_LIST *listNode;
89
    int numPixels;
90
} PALETTE_ENTRY;
91
92
typedef struct PALETTE_s {
93
    PALETTE_ENTRY entry[256];
94
    COLOR_LIST *hash[256];
95
    COLOR_LIST list[256];
96
} PALETTE;
97
98
static int paletteNumColors, paletteMaxColors;
99
static CARD32 monoBackground, monoForeground;
100
static PALETTE palette;
101
102
/* Pointers to dynamically-allocated buffers. */
103
104
static int tightBeforeBufSize = 0;
105
static unsigned char *tightBeforeBuf = NULL;
106
107
static int tightAfterBufSize = 0;
108
static unsigned char *tightAfterBuf = NULL;
109
110
static int *prevRowBuf = NULL;
111
112
113
/* Prototypes for static functions. */
114
115
static void FindBestSolidArea (ScreenPtr pScreen, int x, int y, int w, int h,
116
                               CARD32 colorValue, int *w_ptr, int *h_ptr);
117
static void ExtendSolidArea   (ScreenPtr pScreen, int x, int y, int w, int h,
118
                               CARD32 colorValue,
119
                               int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr);
120
static Bool CheckSolidTile    (ScreenPtr pScreen, int x, int y, int w, int h,
121
                               CARD32 *colorPtr, Bool needSameColor);
122
static Bool CheckSolidTile8   (ScreenPtr pScreen, int x, int y, int w, int h,
123
                               CARD32 *colorPtr, Bool needSameColor);
124
static Bool CheckSolidTile16  (ScreenPtr pScreen, int x, int y, int w, int h,
125
                               CARD32 *colorPtr, Bool needSameColor);
126
static Bool CheckSolidTile32  (ScreenPtr pScreen, int x, int y, int w, int h,
127
                               CARD32 *colorPtr, Bool needSameColor);
128
129
static Bool SendRectSimple    (rfbClientPtr cl, int x, int y, int w, int h);
130
static Bool SendSubrect       (rfbClientPtr cl, int x, int y, int w, int h);
131
static Bool SendTightHeader   (rfbClientPtr cl, int x, int y, int w, int h);
132
133
static Bool SendSolidRect     (rfbClientPtr cl);
134
static Bool SendMonoRect      (rfbClientPtr cl, int w, int h);
135
static Bool SendIndexedRect   (rfbClientPtr cl, int w, int h);
136
static Bool SendFullColorRect (rfbClientPtr cl, int w, int h);
137
static Bool SendGradientRect  (rfbClientPtr cl, int w, int h);
138
139
static Bool CompressData(rfbClientPtr cl, int streamId, int dataLen,
140
                         int zlibLevel, int zlibStrategy);
141
static Bool SendCompressedData(rfbClientPtr cl, int compressedLen);
142
143
static void FillPalette8(int count);
144
static void FillPalette16(int count);
145
static void FillPalette32(int count);
146
147
static void PaletteReset(void);
148
static int PaletteInsert(CARD32 rgb, int numPixels, int bpp);
149
150
static void Pack24(ScreenPtr pScreen, unsigned char *buf, rfbPixelFormat *fmt, int count);
151
152
static void EncodeIndexedRect16(CARD8 *buf, int count);
153
static void EncodeIndexedRect32(CARD8 *buf, int count);
154
155
static void EncodeMonoRect8(CARD8 *buf, int w, int h);
156
static void EncodeMonoRect16(CARD8 *buf, int w, int h);
157
static void EncodeMonoRect32(CARD8 *buf, int w, int h);
158
159
static void FilterGradient24(ScreenPtr pScreen, unsigned char *buf, rfbPixelFormat *fmt, int w, int h);
160
static void FilterGradient16(ScreenPtr pScreen, CARD16 *buf, rfbPixelFormat *fmt, int w, int h);
161
static void FilterGradient32(ScreenPtr pScreen, CARD32 *buf, rfbPixelFormat *fmt, int w, int h);
162
163
static int DetectSmoothImage(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h);
164
static unsigned long DetectSmoothImage24(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h);
165
static unsigned long DetectSmoothImage16(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h);
166
static unsigned long DetectSmoothImage32(rfbClientPtr cl, rfbPixelFormat *fmt, int w, int h);
167
168
static Bool SendJpegRect(rfbClientPtr cl, const CARD8 *buffer, int w, int h, int quality);
169
static void PrepareRowForJpeg(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, int row, int width);
170
static void PrepareRowForJpeg24(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, int row, int width);
171
static void PrepareRowForJpeg16(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, int row, int width);
172
static void PrepareRowForJpeg32(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer, int row, int width);
173
174
static void JpegInitDestination(j_compress_ptr cinfo);
175
static boolean JpegEmptyOutputBuffer(j_compress_ptr cinfo);
176
static void JpegTermDestination(j_compress_ptr cinfo);
177
static void JpegSetDstManager(j_compress_ptr cinfo);
178
179
180
/*
181
 * Tight encoding implementation.
182
 */
183
184
int
185
rfbNumCodedRectsTight(cl, x, y, w, h)
186
    rfbClientPtr cl;
187
    int x, y, w, h;
188
{
189
    int maxRectSize, maxRectWidth;
190
    int subrectMaxWidth, subrectMaxHeight;
191
192
    /* No matter how many rectangles we will send if LastRect markers
193
       are used to terminate rectangle stream. */
194
    if (cl->enableLastRectEncoding && w * h >= MIN_SPLIT_RECT_SIZE)
195
      return 0;
196
197
    maxRectSize = tightConf[cl->tightCompressLevel].maxRectSize;
198
    maxRectWidth = tightConf[cl->tightCompressLevel].maxRectWidth;
199
200
    if (w > maxRectWidth || w * h > maxRectSize) {
201
        subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w;
202
        subrectMaxHeight = maxRectSize / subrectMaxWidth;
203
        return (((w - 1) / maxRectWidth + 1) *
204
                ((h - 1) / subrectMaxHeight + 1));
205
    } else {
206
        return 1;
207
    }
208
}
209
210
Bool
211
rfbSendRectEncodingTight(cl, x, y, w, h)
212
    rfbClientPtr cl;
213
    int x, y, w, h;
214
{
215
    VNCSCREENPTR(cl->pScreen);
216
    int nMaxRows;
217
    CARD32 colorValue;
218
    int dx, dy, dw, dh;
219
    int x_best, y_best, w_best, h_best;
220
221
    if ( cl->format.depth == 24 && cl->format.redMax == 0xFF &&
222
         cl->format.greenMax == 0xFF && cl->format.blueMax == 0xFF ) {
223
        usePixelFormat24 = TRUE;
224
    } else {
225
        usePixelFormat24 = FALSE;
226
    }
227
228
    if (!cl->enableLastRectEncoding || w * h < MIN_SPLIT_RECT_SIZE)
229
        return SendRectSimple(cl, x, y, w, h);
230
231
    /* Make sure we can write at least one pixel into tightBeforeBuf. */
232
233
    if (tightBeforeBufSize < 4) {
234
        tightBeforeBufSize = 4;
235
        if (tightBeforeBuf == NULL)
236
            tightBeforeBuf = (unsigned char *)xalloc(tightBeforeBufSize);
237
        else
238
            tightBeforeBuf = (unsigned char *)xrealloc(tightBeforeBuf,
239
                                              tightBeforeBufSize);
240
    }
241
242
    /* Calculate maximum number of rows in one non-solid rectangle. */
243
244
    {
245
        int maxRectSize, maxRectWidth, nMaxWidth;
246
247
        maxRectSize = tightConf[cl->tightCompressLevel].maxRectSize;
248
        maxRectWidth = tightConf[cl->tightCompressLevel].maxRectWidth;
249
        nMaxWidth = (w > maxRectWidth) ? maxRectWidth : w;
250
        nMaxRows = maxRectSize / nMaxWidth;
251
    }
252
253
    /* Try to find large solid-color areas and send them separately. */
254
255
    for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) {
256
257
        /* If a rectangle becomes too large, send its upper part now. */
258
259
        if (dy - y >= nMaxRows) {
260
            if (!SendRectSimple(cl, x, y, w, nMaxRows))
261
                return 0;
262
            y += nMaxRows;
263
            h -= nMaxRows;
264
        }
265
266
        dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ?
267
            MAX_SPLIT_TILE_SIZE : (y + h - dy);
268
269
        for (dx = x; dx < x + w; dx += MAX_SPLIT_TILE_SIZE) {
270
271
            dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w) ?
272
                MAX_SPLIT_TILE_SIZE : (x + w - dx);
273
274
            if (CheckSolidTile(cl->pScreen, dx, dy, dw, dh, &colorValue, FALSE)) {
275
276
                /* Get dimensions of solid-color area. */
277
278
                FindBestSolidArea(cl->pScreen, dx, dy, w - (dx - x), h - (dy - y),
279
				  colorValue, &w_best, &h_best);
280
281
                /* Make sure a solid rectangle is large enough
282
                   (or the whole rectangle is of the same color). */
283
284
                if ( w_best * h_best != w * h &&
285
                     w_best * h_best < MIN_SOLID_SUBRECT_SIZE )
286
                    continue;
287
288
                /* Try to extend solid rectangle to maximum size. */
289
290
                x_best = dx; y_best = dy;
291
                ExtendSolidArea(cl->pScreen, x, y, w, h, colorValue,
292
                                &x_best, &y_best, &w_best, &h_best);
293
294
                /* Send rectangles at top and left to solid-color area. */
295
296
                if ( y_best != y &&
297
                     !SendRectSimple(cl, x, y, w, y_best-y) )
298
                    return FALSE;
299
                if ( x_best != x &&
300
                     !rfbSendRectEncodingTight(cl, x, y_best,
301
                                               x_best-x, h_best) )
302
                    return FALSE;
303
304
                /* Send solid-color rectangle. */
305
306
                if (!SendTightHeader(cl, x_best, y_best, w_best, h_best))
307
                    return FALSE;
308
309
                (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, 
310
				   &pVNC->rfbServerFormat,
311
                                   &cl->format, tightBeforeBuf,
312
                                   pVNC->paddedWidthInBytes, 1, 1, 
313
				   x_best, y_best);
314
315
                if (!SendSolidRect(cl))
316
                    return FALSE;
317
318
                /* Send remaining rectangles (at right and bottom). */
319
320
                if ( x_best + w_best != x + w &&
321
                     !rfbSendRectEncodingTight(cl, x_best+w_best, y_best,
322
                                               w-(x_best-x)-w_best, h_best) )
323
                    return FALSE;
324
                if ( y_best + h_best != y + h &&
325
                     !rfbSendRectEncodingTight(cl, x, y_best+h_best,
326
                                               w, h-(y_best-y)-h_best) )
327
                    return FALSE;
328
329
                /* Return after all recursive calls are done. */
330
331
                return TRUE;
332
            }
333
334
        }
335
336
    }
337
338
    /* No suitable solid-color rectangles found. */
339
340
    return SendRectSimple(cl, x, y, w, h);
341
}
342
343
static void
344
FindBestSolidArea(pScreen, x, y, w, h, colorValue, w_ptr, h_ptr)
345
    ScreenPtr pScreen;
346
    int x, y, w, h;
347
    CARD32 colorValue;
348
    int *w_ptr, *h_ptr;
349
{
350
    int dx, dy, dw, dh;
351
    int w_prev;
352
    int w_best = 0, h_best = 0;
353
354
    w_prev = w;
355
356
    for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) {
357
358
        dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ?
359
            MAX_SPLIT_TILE_SIZE : (y + h - dy);
360
        dw = (w_prev > MAX_SPLIT_TILE_SIZE) ?
361
            MAX_SPLIT_TILE_SIZE : w_prev;
362
363
        if (!CheckSolidTile(pScreen, x, dy, dw, dh, &colorValue, TRUE))
364
            break;
365
366
        for (dx = x + dw; dx < x + w_prev;) {
367
            dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w_prev) ?
368
                MAX_SPLIT_TILE_SIZE : (x + w_prev - dx);
369
            if (!CheckSolidTile(pScreen, dx, dy, dw, dh, &colorValue, TRUE))
370
                break;
371
	    dx += dw;
372
        }
373
374
        w_prev = dx - x;
375
        if (w_prev * (dy + dh - y) > w_best * h_best) {
376
            w_best = w_prev;
377
            h_best = dy + dh - y;
378
        }
379
    }
380
381
    *w_ptr = w_best;
382
    *h_ptr = h_best;
383
}
384
385
static void
386
ExtendSolidArea(pScreen, x, y, w, h, colorValue, x_ptr, y_ptr, w_ptr, h_ptr)
387
    ScreenPtr pScreen;
388
    int x, y, w, h;
389
    CARD32 colorValue;
390
    int *x_ptr, *y_ptr, *w_ptr, *h_ptr;
391
{
392
    int cx, cy;
393
394
    /* Try to extend the area upwards. */
395
    for ( cy = *y_ptr - 1;
396
          cy >= y && CheckSolidTile(pScreen, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE);
397
          cy-- );
398
    *h_ptr += *y_ptr - (cy + 1);
399
    *y_ptr = cy + 1;
400
401
    /* ... downwards. */
402
    for ( cy = *y_ptr + *h_ptr;
403
          cy < y + h &&
404
              CheckSolidTile(pScreen, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE);
405
          cy++ );
406
    *h_ptr += cy - (*y_ptr + *h_ptr);
407
408
    /* ... to the left. */
409
    for ( cx = *x_ptr - 1;
410
          cx >= x && CheckSolidTile(pScreen, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE);
411
          cx-- );
412
    *w_ptr += *x_ptr - (cx + 1);
413
    *x_ptr = cx + 1;
414
415
    /* ... to the right. */
416
    for ( cx = *x_ptr + *w_ptr;
417
          cx < x + w &&
418
              CheckSolidTile(pScreen, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE);
419
          cx++ );
420
    *w_ptr += cx - (*x_ptr + *w_ptr);
421
}
422
423
/*
424
 * Check if a rectangle is all of the same color. If needSameColor is
425
 * set to non-zero, then also check that its color equals to the
426
 * *colorPtr value. The result is 1 if the test is successfull, and in
427
 * that case new color will be stored in *colorPtr.
428
 */
429
430
static Bool
431
CheckSolidTile(pScreen, x, y, w, h, colorPtr, needSameColor) 
432
    ScreenPtr pScreen;
433
    int x, y, w, h;
434
    CARD32 *colorPtr;
435
    Bool needSameColor;
436
{
437
    VNCSCREENPTR(pScreen);
438
    switch(pVNC->rfbServerFormat.bitsPerPixel) {
439
    case 32:
440
        return CheckSolidTile32(pScreen, x, y, w, h, colorPtr, needSameColor);
441
    case 16:
442
        return CheckSolidTile16(pScreen, x, y, w, h, colorPtr, needSameColor);
443
    default:
444
        return CheckSolidTile8(pScreen, x, y, w, h, colorPtr, needSameColor);
445
    }
446
}
447
448
#define DEFINE_CHECK_SOLID_FUNCTION(bpp)                                      \
449
                                                                              \
450
static Bool                                                                   \
451
CheckSolidTile##bpp(pScreen, x, y, w, h, colorPtr, needSameColor)             \
452
    ScreenPtr pScreen;							      \
453
    int x, y;                                                                 \
454
    CARD32 *colorPtr;                                                         \
455
    Bool needSameColor;                                                       \
456
{                                                                             \
457
    VNCSCREENPTR(pScreen);						      \
458
    CARD##bpp *fbptr;                                                         \
459
    CARD##bpp colorValue;                                                     \
460
    int dx, dy;                                                               \
461
                                                                              \
462
    fbptr = (CARD##bpp *)                                                     \
463
        &pVNC->pfbMemory[y * pVNC->paddedWidthInBytes + x * (bpp/8)]; \
464
                                                                              \
465
    colorValue = *fbptr;                                                      \
466
    if (needSameColor && (CARD32)colorValue != *colorPtr)                     \
467
        return FALSE;                                                         \
468
                                                                              \
469
    for (dy = 0; dy < h; dy++) {                                              \
470
        for (dx = 0; dx < w; dx++) {                                          \
471
            if (colorValue != fbptr[dx])                                      \
472
                return FALSE;                                                 \
473
        }                                                                     \
474
        fbptr = (CARD##bpp *)((CARD8 *)fbptr + pVNC->paddedWidthInBytes);     \
475
    }                                                                         \
476
                                                                              \
477
    *colorPtr = (CARD32)colorValue;                                           \
478
    return TRUE;                                                              \
479
}
480
481
DEFINE_CHECK_SOLID_FUNCTION(8)
482
DEFINE_CHECK_SOLID_FUNCTION(16)
483
DEFINE_CHECK_SOLID_FUNCTION(32)
484
485
static Bool
486
SendRectSimple(cl, x, y, w, h)
487
    rfbClientPtr cl;
488
    int x, y, w, h;
489
{
490
    int maxBeforeSize, maxAfterSize;
491
    int maxRectSize, maxRectWidth;
492
    int subrectMaxWidth, subrectMaxHeight;
493
    int dx, dy;
494
    int rw, rh;
495
496
    maxRectSize = tightConf[cl->tightCompressLevel].maxRectSize;
497
    maxRectWidth = tightConf[cl->tightCompressLevel].maxRectWidth;
498
499
    maxBeforeSize = maxRectSize * (cl->format.bitsPerPixel / 8);
500
    maxAfterSize = maxBeforeSize + (maxBeforeSize + 99) / 100 + 12;
501
502
    if (tightBeforeBufSize < maxBeforeSize) {
503
        tightBeforeBufSize = maxBeforeSize;
504
        if (tightBeforeBuf == NULL)
505
            tightBeforeBuf = (unsigned char *)xalloc(tightBeforeBufSize);
506
        else
507
            tightBeforeBuf = (unsigned char *)xrealloc(tightBeforeBuf,
508
                                              tightBeforeBufSize);
509
    }
510
511
    if (tightAfterBufSize < maxAfterSize) {
512
        tightAfterBufSize = maxAfterSize;
513
        if (tightAfterBuf == NULL)
514
            tightAfterBuf = (unsigned char *)xalloc(tightAfterBufSize);
515
        else
516
            tightAfterBuf = (unsigned char *)xrealloc(tightAfterBuf,
517
                                             tightAfterBufSize);
518
    }
519
520
    if (w > maxRectWidth || w * h > maxRectSize) {
521
        subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w;
522
        subrectMaxHeight = maxRectSize / subrectMaxWidth;
523
524
        for (dy = 0; dy < h; dy += subrectMaxHeight) {
525
            for (dx = 0; dx < w; dx += maxRectWidth) {
526
                rw = (dx + maxRectWidth < w) ? maxRectWidth : w - dx;
527
                rh = (dy + subrectMaxHeight < h) ? subrectMaxHeight : h - dy;
528
                if (!SendSubrect(cl, x+dx, y+dy, rw, rh))
529
                    return FALSE;
530
            }
531
        }
532
    } else {
533
        if (!SendSubrect(cl, x, y, w, h))
534
            return FALSE;
535
    }
536
537
    return TRUE;
538
}
539
540
static Bool
541
SendSubrect(cl, x, y, w, h)
542
    rfbClientPtr cl;
543
    int x, y, w, h;
544
{
545
    VNCSCREENPTR(cl->pScreen);
546
    Bool success = FALSE;
547
548
    /* Send pending data if there is more than 128 bytes. */
549
    if (pVNC->ublen > 128) {
550
        if (!rfbSendUpdateBuf(cl))
551
            return FALSE;
552
    }
553
554
    if (!SendTightHeader(cl, x, y, w, h))
555
        return FALSE;
556
557
    (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, &pVNC->rfbServerFormat,
558
                       &cl->format, tightBeforeBuf,
559
                       pVNC->paddedWidthInBytes, w, h, x, y);
560
561
    paletteMaxColors = w * h / tightConf[cl->tightCompressLevel].idxMaxColorsDivisor;
562
    if ( paletteMaxColors < 2 &&
563
         w * h >= tightConf[cl->tightCompressLevel].monoMinRectSize ) {
564
        paletteMaxColors = 2;
565
    }
566
    switch (cl->format.bitsPerPixel) {
567
    case 8:
568
        FillPalette8(w * h);
569
        break;
570
    case 16:
571
        FillPalette16(w * h);
572
        break;
573
    default:
574
        FillPalette32(w * h);
575
    }
576
577
    switch (paletteNumColors) {
578
    case 0:
579
        /* Truecolor image */
580
        if (DetectSmoothImage(cl, &cl->format, w, h)) {
581
            if (cl->tightQualityLevel != -1) {
582
                success = SendJpegRect(cl, tightBeforeBuf, w, h,
583
                                  tightConf[cl->tightQualityLevel].jpegQuality);
584
            } else {
585
                success = SendGradientRect(cl, w, h);
586
            }
587
        } else {
588
            success = SendFullColorRect(cl, w, h);
589
        }
590
        break;
591
    case 1:
592
        /* Solid rectangle */
593
        success = SendSolidRect(cl);
594
        break;
595
    case 2:
596
        /* Two-color rectangle */
597
        success = SendMonoRect(cl, w, h);
598
        break;
599
    default:
600
        /* Up to 256 different colors */
601
        if ( paletteNumColors > 96 &&
602
             cl->tightQualityLevel != -1 && cl->tightQualityLevel <= 3 &&
603
             DetectSmoothImage(cl, &cl->format, w, h) ) {
604
            success = SendJpegRect(cl, tightBeforeBuf, w, h,
605
                                  tightConf[cl->tightQualityLevel].jpegQuality);
606
        } else {
607
            success = SendIndexedRect(cl, w, h);
608
        }
609
    }
610
    return success;
611
}
612
613
static Bool
614
SendTightHeader(cl, x, y, w, h)
615
    rfbClientPtr cl;
616
    int x, y, w, h;
617
{
618
    VNCSCREENPTR(cl->pScreen);
619
    rfbFramebufferUpdateRectHeader rect;
620
621
    if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
622
        if (!rfbSendUpdateBuf(cl))
623
            return FALSE;
624
    }
625
626
    rect.r.x = Swap16IfLE(x);
627
    rect.r.y = Swap16IfLE(y);
628
    rect.r.w = Swap16IfLE(w);
629
    rect.r.h = Swap16IfLE(h);
630
    rect.encoding = Swap32IfLE(rfbEncodingTight);
631
632
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,
633
           sz_rfbFramebufferUpdateRectHeader);
634
    pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
635
636
    cl->rfbRectanglesSent[rfbEncodingTight]++;
637
    cl->rfbBytesSent[rfbEncodingTight] += sz_rfbFramebufferUpdateRectHeader;
638
639
    return TRUE;
640
}
641
642
/*
643
 * Subencoding implementations.
644
 */
645
646
static Bool
647
SendSolidRect(cl)
648
    rfbClientPtr cl;
649
{
650
    VNCSCREENPTR(cl->pScreen);
651
    int len;
652
653
    if (usePixelFormat24) {
654
        Pack24(cl->pScreen, tightBeforeBuf, &cl->format, 1);
655
        len = 3;
656
    } else
657
        len = cl->format.bitsPerPixel / 8;
658
659
    if (pVNC->ublen + 1 + len > UPDATE_BUF_SIZE) {
660
        if (!rfbSendUpdateBuf(cl))
661
            return FALSE;
662
    }
663
664
    pVNC->updateBuf[pVNC->ublen++] = (char)(rfbTightFill << 4);
665
    memcpy (&pVNC->updateBuf[pVNC->ublen], tightBeforeBuf, len);
666
    pVNC->ublen += len;
667
668
    cl->rfbBytesSent[rfbEncodingTight] += len + 1;
669
670
    return TRUE;
671
}
672
673
static Bool
674
SendMonoRect(cl, w, h)
675
    rfbClientPtr cl;
676
    int w, h;
677
{
678
    VNCSCREENPTR(cl->pScreen);
679
    int streamId = 1;
680
    int paletteLen, dataLen;
681
682
    if ( (pVNC->ublen + TIGHT_MIN_TO_COMPRESS + 6 +
683
          2 * cl->format.bitsPerPixel / 8) > UPDATE_BUF_SIZE ) {
684
        if (!rfbSendUpdateBuf(cl))
685
            return FALSE;
686
    }
687
688
    /* Prepare tight encoding header. */
689
    dataLen = (w + 7) / 8;
690
    dataLen *= h;
691
692
    pVNC->updateBuf[pVNC->ublen++] = (streamId | rfbTightExplicitFilter) << 4;
693
    pVNC->updateBuf[pVNC->ublen++] = rfbTightFilterPalette;
694
    pVNC->updateBuf[pVNC->ublen++] = 1;
695
696
    /* Prepare palette, convert image. */
697
    switch (cl->format.bitsPerPixel) {
698
699
    case 32:
700
        EncodeMonoRect32((CARD8 *)tightBeforeBuf, w, h);
701
702
        ((CARD32 *)tightAfterBuf)[0] = monoBackground;
703
        ((CARD32 *)tightAfterBuf)[1] = monoForeground;
704
        if (usePixelFormat24) {
705
            Pack24(cl->pScreen, tightAfterBuf, &cl->format, 2);
706
            paletteLen = 6;
707
        } else
708
            paletteLen = 8;
709
710
        memcpy(&pVNC->updateBuf[pVNC->ublen], tightAfterBuf, paletteLen);
711
        pVNC->ublen += paletteLen;
712
        cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteLen;
713
        break;
714
715
    case 16:
716
        EncodeMonoRect16((CARD8 *)tightBeforeBuf, w, h);
717
718
        ((CARD16 *)tightAfterBuf)[0] = (CARD16)monoBackground;
719
        ((CARD16 *)tightAfterBuf)[1] = (CARD16)monoForeground;
720
721
        memcpy(&pVNC->updateBuf[pVNC->ublen], tightAfterBuf, 4);
722
        pVNC->ublen += 4;
723
        cl->rfbBytesSent[rfbEncodingTight] += 7;
724
        break;
725
726
    default:
727
        EncodeMonoRect8((CARD8 *)tightBeforeBuf, w, h);
728
729
        pVNC->updateBuf[pVNC->ublen++] = (char)monoBackground;
730
        pVNC->updateBuf[pVNC->ublen++] = (char)monoForeground;
731
        cl->rfbBytesSent[rfbEncodingTight] += 5;
732
    }
733
734
    return CompressData(cl, streamId, dataLen,
735
                        tightConf[cl->tightCompressLevel].monoZlibLevel,
736
                        Z_DEFAULT_STRATEGY);
737
}
738
739
static Bool
740
SendIndexedRect(cl, w, h)
741
    rfbClientPtr cl;
742
    int w, h;
743
{
744
    VNCSCREENPTR(cl->pScreen);
745
    int streamId = 2;
746
    int i, entryLen;
747
748
    if ( (pVNC->ublen + TIGHT_MIN_TO_COMPRESS + 6 +
749
          paletteNumColors * cl->format.bitsPerPixel / 8) > UPDATE_BUF_SIZE ) {
750
        if (!rfbSendUpdateBuf(cl))
751
            return FALSE;
752
    }
753
754
    /* Prepare tight encoding header. */
755
    pVNC->updateBuf[pVNC->ublen++] = (streamId | rfbTightExplicitFilter) << 4;
756
    pVNC->updateBuf[pVNC->ublen++] = rfbTightFilterPalette;
757
    pVNC->updateBuf[pVNC->ublen++] = (char)(paletteNumColors - 1);
758
759
    /* Prepare palette, convert image. */
760
    switch (cl->format.bitsPerPixel) {
761
762
    case 32:
763
        EncodeIndexedRect32((CARD8 *)tightBeforeBuf, w * h);
764
765
        for (i = 0; i < paletteNumColors; i++) {
766
            ((CARD32 *)tightAfterBuf)[i] =
767
                palette.entry[i].listNode->rgb;
768
        }
769
        if (usePixelFormat24) {
770
            Pack24(cl->pScreen, tightAfterBuf, &cl->format, paletteNumColors);
771
            entryLen = 3;
772
        } else
773
            entryLen = 4;
774
775
        memcpy(&pVNC->updateBuf[pVNC->ublen], tightAfterBuf, paletteNumColors * entryLen);
776
        pVNC->ublen += paletteNumColors * entryLen;
777
        cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteNumColors * entryLen;
778
        break;
779
780
    case 16:
781
        EncodeIndexedRect16((CARD8 *)tightBeforeBuf, w * h);
782
783
        for (i = 0; i < paletteNumColors; i++) {
784
            ((CARD16 *)tightAfterBuf)[i] =
785
                (CARD16)palette.entry[i].listNode->rgb;
786
        }
787
788
        memcpy(&pVNC->updateBuf[pVNC->ublen], tightAfterBuf, paletteNumColors * 2);
789
        pVNC->ublen += paletteNumColors * 2;
790
        cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteNumColors * 2;
791
        break;
792
793
    default:
794
        return FALSE;           /* Should never happen. */
795
    }
796
797
    return CompressData(cl, streamId, w * h,
798
                        tightConf[cl->tightCompressLevel].idxZlibLevel,
799
                        Z_DEFAULT_STRATEGY);
800
}
801
802
static Bool
803
SendFullColorRect(cl, w, h)
804
    rfbClientPtr cl;
805
    int w, h;
806
{
807
    VNCSCREENPTR(cl->pScreen);
808
    int streamId = 0;
809
    int len;
810
811
    if (pVNC->ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) {
812
        if (!rfbSendUpdateBuf(cl))
813
            return FALSE;
814
    }
815
816
    pVNC->updateBuf[pVNC->ublen++] = 0x00;  /* stream id = 0, no flushing, no filter */
817
    cl->rfbBytesSent[rfbEncodingTight]++;
818
819
    if (usePixelFormat24) {
820
        Pack24(cl->pScreen, tightBeforeBuf, &cl->format, w * h);
821
        len = 3;
822
    } else
823
        len = cl->format.bitsPerPixel / 8;
824
825
    return CompressData(cl, streamId, w * h * len,
826
                        tightConf[cl->tightCompressLevel].rawZlibLevel,
827
                        Z_DEFAULT_STRATEGY);
828
}
829
830
static Bool
831
SendGradientRect(cl, w, h)
832
    rfbClientPtr cl;
833
    int w, h;
834
{
835
    VNCSCREENPTR(cl->pScreen);
836
    int streamId = 3;
837
    int len;
838
839
    if (cl->format.bitsPerPixel == 8)
840
        return SendFullColorRect(cl, w, h);
841
842
    if (pVNC->ublen + TIGHT_MIN_TO_COMPRESS + 2 > UPDATE_BUF_SIZE) {
843
        if (!rfbSendUpdateBuf(cl))
844
            return FALSE;
845
    }
846
847
    if (prevRowBuf == NULL)
848
        prevRowBuf = (int *)xalloc(2048 * 3 * sizeof(int));
849
850
    pVNC->updateBuf[pVNC->ublen++] = (streamId | rfbTightExplicitFilter) << 4;
851
    pVNC->updateBuf[pVNC->ublen++] = rfbTightFilterGradient;
852
    cl->rfbBytesSent[rfbEncodingTight] += 2;
853
854
    if (usePixelFormat24) {
855
        FilterGradient24(cl->pScreen, tightBeforeBuf, &cl->format, w, h);
856
        len = 3;
857
    } else if (cl->format.bitsPerPixel == 32) {
858
        FilterGradient32(cl->pScreen, (CARD32 *)tightBeforeBuf, &cl->format, w, h);
859
        len = 4;
860
    } else {
861
        FilterGradient16(cl->pScreen, (CARD16 *)tightBeforeBuf, &cl->format, w, h);
862
        len = 2;
863
    }
864
865
    return CompressData(cl, streamId, w * h * len,
866
                        tightConf[cl->tightCompressLevel].gradientZlibLevel,
867
                        Z_FILTERED);
868
}
869
870
/**
871
 * Compress the data in the tightBeforeBuf buffer.
872
 * \param  dataLen - amount of data in tightBeforeBuf to compress, in bytes
873
 */
874
static Bool
875
CompressData(cl, streamId, dataLen, zlibLevel, zlibStrategy)
876
    rfbClientPtr cl;
877
    int streamId, dataLen, zlibLevel, zlibStrategy;
878
{
879
    VNCSCREENPTR(cl->pScreen);
880
    z_streamp pz;
881
    int err;
882
883
    if (dataLen < TIGHT_MIN_TO_COMPRESS) {
884
        memcpy(&pVNC->updateBuf[pVNC->ublen], tightBeforeBuf, dataLen);
885
        pVNC->ublen += dataLen;
886
        cl->rfbBytesSent[rfbEncodingTight] += dataLen;
887
        return TRUE;
888
    }
889
890
    pz = &cl->zsStruct[streamId];
891
892
    /* Initialize compression stream if needed. */
893
    if (!cl->zsActive[streamId]) {
894
        pz->zalloc = Z_NULL;
895
        pz->zfree = Z_NULL;
896
        pz->opaque = Z_NULL;
897
898
        err = deflateInit2 (pz, zlibLevel, Z_DEFLATED, MAX_WBITS,
899
                            MAX_MEM_LEVEL, zlibStrategy);
900
        if (err != Z_OK)
901
            return FALSE;
902
903
        cl->zsActive[streamId] = TRUE;
904
        cl->zsLevel[streamId] = zlibLevel;
905
    }
906
907
    /* Prepare buffer pointers. */
908
    pz->next_in = (Bytef *)tightBeforeBuf;
909
    pz->avail_in = dataLen;
910
    pz->next_out = (Bytef *)tightAfterBuf;
911
    pz->avail_out = tightAfterBufSize;
912
913
    /* Change compression parameters if needed. */
914
    if (zlibLevel != cl->zsLevel[streamId]) {
915
        if (deflateParams (pz, zlibLevel, zlibStrategy) != Z_OK) {
916
            return FALSE;
917
        }
918
        cl->zsLevel[streamId] = zlibLevel;
919
    }
920
921
    /* Actual compression. */
922
    if ( deflate (pz, Z_SYNC_FLUSH) != Z_OK ||
923
         pz->avail_in != 0 || pz->avail_out == 0 ) {
924
        return FALSE;
925
    }
926
927
    return SendCompressedData(cl, tightAfterBufSize - pz->avail_out);
928
}
929
930
static Bool SendCompressedData(cl, compressedLen)
931
    rfbClientPtr cl;
932
    int compressedLen;
933
{
934
    VNCSCREENPTR(cl->pScreen);
935
    int i, portionLen;
936
937
    pVNC->updateBuf[pVNC->ublen++] = compressedLen & 0x7F;
938
    cl->rfbBytesSent[rfbEncodingTight]++;
939
    if (compressedLen > 0x7F) {
940
        pVNC->updateBuf[pVNC->ublen-1] |= 0x80;
941
        pVNC->updateBuf[pVNC->ublen++] = compressedLen >> 7 & 0x7F;
942
        cl->rfbBytesSent[rfbEncodingTight]++;
943
        if (compressedLen > 0x3FFF) {
944
            pVNC->updateBuf[pVNC->ublen-1] |= 0x80;
945
            pVNC->updateBuf[pVNC->ublen++] = compressedLen >> 14 & 0xFF;
946
            cl->rfbBytesSent[rfbEncodingTight]++;
947
        }
948
    }
949
950
    portionLen = UPDATE_BUF_SIZE;
951
    for (i = 0; i < compressedLen; i += portionLen) {
952
        if (i + portionLen > compressedLen) {
953
            portionLen = compressedLen - i;
954
        }
955
        if (pVNC->ublen + portionLen > UPDATE_BUF_SIZE) {
956
            if (!rfbSendUpdateBuf(cl))
957
                return FALSE;
958
        }
959
        memcpy(&pVNC->updateBuf[pVNC->ublen], &tightAfterBuf[i], portionLen);
960
        pVNC->ublen += portionLen;
961
    }
962
    cl->rfbBytesSent[rfbEncodingTight] += compressedLen;
963
    return TRUE;
964
}
965
966
/*
967
 * Code to determine how many different colors used in rectangle.
968
 */
969
970
static void
971
FillPalette8(count)
972
    int count;
973
{
974
    CARD8 *data = (CARD8 *)tightBeforeBuf;
975
    CARD8 c0, c1;
976
    int i, n0, n1;
977
978
    paletteNumColors = 0;
979
980
    c0 = data[0];
981
    for (i = 1; i < count && data[i] == c0; i++);
982
    if (i == count) {
983
        paletteNumColors = 1;
984
        return;                 /* Solid rectangle */
985
    }
986
987
    if (paletteMaxColors < 2)
988
        return;
989
990
    n0 = i;
991
    c1 = data[i];
992
    n1 = 0;
993
    for (i++; i < count; i++) {
994
        if (data[i] == c0) {
995
            n0++;
996
        } else if (data[i] == c1) {
997
            n1++;
998
        } else
999
            break;
1000
    }
1001
    if (i == count) {
1002
        if (n0 > n1) {
1003
            monoBackground = (CARD32)c0;
1004
            monoForeground = (CARD32)c1;
1005
        } else {
1006
            monoBackground = (CARD32)c1;
1007
            monoForeground = (CARD32)c0;
1008
        }
1009
        paletteNumColors = 2;   /* Two colors */
1010
    }
1011
}
1012
1013
#define DEFINE_FILL_PALETTE_FUNCTION(bpp)                               \
1014
                                                                        \
1015
static void                                                             \
1016
FillPalette##bpp(count)                                                 \
1017
    int count;                                                          \
1018
{                                                                       \
1019
    CARD##bpp *data = (CARD##bpp *)tightBeforeBuf;                      \
1020
    CARD##bpp c0, c1, ci = 0;                                           \
1021
    int i, n0, n1, ni;                                                  \
1022
                                                                        \
1023
    c0 = data[0];                                                       \
1024
    for (i = 1; i < count && data[i] == c0; i++);                       \
1025
    if (i >= count) {                                                   \
1026
        paletteNumColors = 1;   /* Solid rectangle */                   \
1027
        return;                                                         \
1028
    }                                                                   \
1029
                                                                        \
1030
    if (paletteMaxColors < 2) {                                         \
1031
        paletteNumColors = 0;   /* Full-color encoding preferred */     \
1032
        return;                                                         \
1033
    }                                                                   \
1034
                                                                        \
1035
    n0 = i;                                                             \
1036
    c1 = data[i];                                                       \
1037
    n1 = 0;                                                             \
1038
    for (i++; i < count; i++) {                                         \
1039
        ci = data[i];                                                   \
1040
        if (ci == c0) {                                                 \
1041
            n0++;                                                       \
1042
        } else if (ci == c1) {                                          \
1043
            n1++;                                                       \
1044
        } else                                                          \
1045
            break;                                                      \
1046
    }                                                                   \
1047
    if (i >= count) {                                                   \
1048
        if (n0 > n1) {                                                  \
1049
            monoBackground = (CARD32)c0;                                \
1050
            monoForeground = (CARD32)c1;                                \
1051
        } else {                                                        \
1052
            monoBackground = (CARD32)c1;                                \
1053
            monoForeground = (CARD32)c0;                                \
1054
        }                                                               \
1055
        paletteNumColors = 2;   /* Two colors */                        \
1056
        return;                                                         \
1057
    }                                                                   \
1058
                                                                        \
1059
    PaletteReset();                                                     \
1060
    PaletteInsert (c0, (CARD32)n0, bpp);                                \
1061
    PaletteInsert (c1, (CARD32)n1, bpp);                                \
1062
                                                                        \
1063
    ni = 1;                                                             \
1064
    for (i++; i < count; i++) {                                         \
1065
        if (data[i] == ci) {                                            \
1066
            ni++;                                                       \
1067
        } else {                                                        \
1068
            if (!PaletteInsert (ci, (CARD32)ni, bpp))                   \
1069
                return;                                                 \
1070
            ci = data[i];                                               \
1071
            ni = 1;                                                     \
1072
        }                                                               \
1073
    }                                                                   \
1074
    PaletteInsert (ci, (CARD32)ni, bpp);                                \
1075
}
1076
1077
DEFINE_FILL_PALETTE_FUNCTION(16)
1078
DEFINE_FILL_PALETTE_FUNCTION(32)
1079
1080
1081
/*
1082
 * Functions to operate with palette structures.
1083
 */
1084
1085
#define HASH_FUNC16(rgb) ((int)((((rgb) >> 8) + (rgb)) & 0xFF))
1086
#define HASH_FUNC32(rgb) ((int)((((rgb) >> 16) + ((rgb) >> 8)) & 0xFF))
1087
1088
static void
1089
PaletteReset(void)
1090
{
1091
    paletteNumColors = 0;
1092
    memset(palette.hash, 0, 256 * sizeof(COLOR_LIST *));
1093
}
1094
1095
static int
1096
PaletteInsert(CARD32 rgb, int numPixels, int bpp)
1097
{
1098
    COLOR_LIST *pnode;
1099
    COLOR_LIST *prev_pnode = NULL;
1100
    int hash_key, idx, new_idx, count;
1101
1102
    hash_key = (bpp == 16) ? HASH_FUNC16(rgb) : HASH_FUNC32(rgb);
1103
1104
    pnode = palette.hash[hash_key];
1105
1106
    while (pnode != NULL) {
1107
        if (pnode->rgb == rgb) {
1108
            /* Such palette entry already exists. */
1109
            new_idx = idx = pnode->idx;
1110
            count = palette.entry[idx].numPixels + numPixels;
1111
            if (new_idx && palette.entry[new_idx-1].numPixels < count) {
1112
                do {
1113
                    palette.entry[new_idx] = palette.entry[new_idx-1];
1114
                    palette.entry[new_idx].listNode->idx = new_idx;
1115
                    new_idx--;
1116
                }
1117
                while (new_idx && palette.entry[new_idx-1].numPixels < count);
1118
                palette.entry[new_idx].listNode = pnode;
1119
                pnode->idx = new_idx;
1120
            }
1121
            palette.entry[new_idx].numPixels = count;
1122
            return paletteNumColors;
1123
        }
1124
        prev_pnode = pnode;
1125
        pnode = pnode->next;
1126
    }
1127
1128
    /* Check if palette is full. */
1129
    if (paletteNumColors == 256 || paletteNumColors == paletteMaxColors) {
1130
        paletteNumColors = 0;
1131
        return 0;
1132
    }
1133
1134
    /* Move palette entries with lesser pixel counts. */
1135
    for ( idx = paletteNumColors;
1136
          idx > 0 && palette.entry[idx-1].numPixels < numPixels;
1137
          idx-- ) {
1138
        palette.entry[idx] = palette.entry[idx-1];
1139
        palette.entry[idx].listNode->idx = idx;
1140
    }
1141
1142
    /* Add new palette entry into the freed slot. */
1143
    pnode = &palette.list[paletteNumColors];
1144
    if (prev_pnode != NULL) {
1145
        prev_pnode->next = pnode;
1146
    } else {
1147
        palette.hash[hash_key] = pnode;
1148
    }
1149
    pnode->next = NULL;
1150
    pnode->idx = idx;
1151
    pnode->rgb = rgb;
1152
    palette.entry[idx].listNode = pnode;
1153
    palette.entry[idx].numPixels = numPixels;
1154
1155
    return (++paletteNumColors);
1156
}
1157
1158
1159
/*
1160
 * Converting 32-bit color samples into 24-bit colors.
1161
 * Should be called only when redMax, greenMax and blueMax are 255.
1162
 * Color components assumed to be byte-aligned.
1163
 */
1164
1165
static void Pack24(pScreen, buf, fmt, count)
1166
    ScreenPtr pScreen;
1167
    unsigned char *buf;
1168
    rfbPixelFormat *fmt;
1169
    int count;
1170
{
1171
    VNCSCREENPTR(pScreen);
1172
    CARD32 *buf32;
1173
    CARD32 pix;
1174
    int r_shift, g_shift, b_shift;
1175
1176
    buf32 = (CARD32 *)buf;
1177
1178
    if (!pVNC->rfbServerFormat.bigEndian == !fmt->bigEndian) {
1179
        r_shift = fmt->redShift;
1180
        g_shift = fmt->greenShift;
1181
        b_shift = fmt->blueShift;
1182
    } else {
1183
        r_shift = 24 - fmt->redShift;
1184
        g_shift = 24 - fmt->greenShift;
1185
        b_shift = 24 - fmt->blueShift;
1186
    }
1187
1188
    while (count--) {
1189
        pix = *buf32++;
1190
        *buf++ = (char)(pix >> r_shift);
1191
        *buf++ = (char)(pix >> g_shift);
1192
        *buf++ = (char)(pix >> b_shift);
1193
    }
1194
}
1195
1196
1197
/*
1198
 * Converting truecolor samples into palette indices.
1199
 */
1200
1201
#define DEFINE_IDX_ENCODE_FUNCTION(bpp)                                 \
1202
                                                                        \
1203
static void                                                             \
1204
EncodeIndexedRect##bpp(buf, count)                                      \
1205
    CARD8 *buf;                                                         \
1206
    int count;                                                          \
1207
{                                                                       \
1208
    COLOR_LIST *pnode;                                                  \
1209
    CARD##bpp *src;                                                     \
1210
    CARD##bpp rgb;                                                      \
1211
    int rep = 0;                                                        \
1212
                                                                        \
1213
    src = (CARD##bpp *) buf;                                            \
1214
                                                                        \
1215
    while (count--) {                                                   \
1216
        rgb = *src++;                                                   \
1217
        while (count && *src == rgb) {                                  \
1218
            rep++, src++, count--;                                      \
1219
        }                                                               \
1220
        pnode = palette.hash[HASH_FUNC##bpp(rgb)];                      \
1221
        while (pnode != NULL) {                                         \
1222
            if ((CARD##bpp)pnode->rgb == rgb) {                         \
1223
                *buf++ = (CARD8)pnode->idx;                             \
1224
                while (rep) {                                           \
1225
                    *buf++ = (CARD8)pnode->idx;                         \
1226
                    rep--;                                              \
1227
                }                                                       \
1228
                break;                                                  \
1229
            }                                                           \
1230
            pnode = pnode->next;                                        \
1231
        }                                                               \
1232
    }                                                                   \
1233
}
1234
1235
DEFINE_IDX_ENCODE_FUNCTION(16)
1236
DEFINE_IDX_ENCODE_FUNCTION(32)
1237
1238
#define DEFINE_MONO_ENCODE_FUNCTION(bpp)                                \
1239
                                                                        \
1240
static void                                                             \
1241
EncodeMonoRect##bpp(buf, w, h)                                          \
1242
    CARD8 *buf;                                                         \
1243
    int w, h;                                                           \
1244
{                                                                       \
1245
    CARD##bpp *ptr;                                                     \
1246
    CARD##bpp bg;                                                       \
1247
    unsigned int value, mask;                                           \
1248
    int aligned_width;                                                  \
1249
    int x, y, bg_bits;                                                  \
1250
                                                                        \
1251
    ptr = (CARD##bpp *) buf;                                            \
1252
    bg = (CARD##bpp) monoBackground;                                    \
1253
    aligned_width = w - w % 8;                                          \
1254
                                                                        \
1255
    for (y = 0; y < h; y++) {                                           \
1256
        for (x = 0; x < aligned_width; x += 8) {                        \
1257
            for (bg_bits = 0; bg_bits < 8; bg_bits++) {                 \
1258
                if (*ptr++ != bg)                                       \
1259
                    break;                                              \
1260
            }                                                           \
1261
            if (bg_bits == 8) {                                         \
1262
                *buf++ = 0;                                             \
1263
                continue;                                               \
1264
            }                                                           \
1265
            mask = 0x80 >> bg_bits;                                     \
1266
            value = mask;                                               \
1267
            for (bg_bits++; bg_bits < 8; bg_bits++) {                   \
1268
                mask >>= 1;                                             \
1269
                if (*ptr++ != bg) {                                     \
1270
                    value |= mask;                                      \
1271
                }                                                       \
1272
            }                                                           \
1273
            *buf++ = (CARD8)value;                                      \
1274
        }                                                               \
1275
                                                                        \
1276
        mask = 0x80;                                                    \
1277
        value = 0;                                                      \
1278
        if (x >= w)                                                     \
1279
            continue;                                                   \
1280
                                                                        \
1281
        for (; x < w; x++) {                                            \
1282
            if (*ptr++ != bg) {                                         \
1283
                value |= mask;                                          \
1284
            }                                                           \
1285
            mask >>= 1;                                                 \
1286
        }                                                               \
1287
        *buf++ = (CARD8)value;                                          \
1288
    }                                                                   \
1289
}
1290
1291
DEFINE_MONO_ENCODE_FUNCTION(8)
1292
DEFINE_MONO_ENCODE_FUNCTION(16)
1293
DEFINE_MONO_ENCODE_FUNCTION(32)
1294
1295
1296
/*
1297
 * ``Gradient'' filter for 24-bit color samples.
1298
 * Should be called only when redMax, greenMax and blueMax are 255.
1299
 * Color components assumed to be byte-aligned.
1300
 */
1301
1302
static void
1303
FilterGradient24(pScreen, buf, fmt, w, h)
1304
    ScreenPtr pScreen;
1305
    unsigned char *buf;
1306
    rfbPixelFormat *fmt;
1307
    int w, h;
1308
{
1309
    VNCSCREENPTR(pScreen);
1310
    CARD32 *buf32;
1311
    CARD32 pix32;
1312
    int *prevRowPtr;
1313
    int shiftBits[3];
1314
    int pixHere[3], pixUpper[3], pixLeft[3], pixUpperLeft[3];
1315
    int prediction;
1316
    int x, y, c;
1317
1318
    buf32 = (CARD32 *)buf;
1319
    memset (prevRowBuf, 0, w * 3 * sizeof(int));
1320
1321
    if (!pVNC->rfbServerFormat.bigEndian == !fmt->bigEndian) {
1322
        shiftBits[0] = fmt->redShift;
1323
        shiftBits[1] = fmt->greenShift;
1324
        shiftBits[2] = fmt->blueShift;
1325
    } else {
1326
        shiftBits[0] = 24 - fmt->redShift;
1327
        shiftBits[1] = 24 - fmt->greenShift;
1328
        shiftBits[2] = 24 - fmt->blueShift;
1329
    }
1330
1331
    for (y = 0; y < h; y++) {
1332
        for (c = 0; c < 3; c++) {
1333
            pixUpper[c] = 0;
1334
            pixHere[c] = 0;
1335
        }
1336
        prevRowPtr = prevRowBuf;
1337
        for (x = 0; x < w; x++) {
1338
            pix32 = *buf32++;
1339
            for (c = 0; c < 3; c++) {
1340
                pixUpperLeft[c] = pixUpper[c];
1341
                pixLeft[c] = pixHere[c];
1342
                pixUpper[c] = *prevRowPtr;
1343
                pixHere[c] = (int)(pix32 >> shiftBits[c] & 0xFF);
1344
                *prevRowPtr++ = pixHere[c];
1345
1346
                prediction = pixLeft[c] + pixUpper[c] - pixUpperLeft[c];
1347
                if (prediction < 0) {
1348
                    prediction = 0;
1349
                } else if (prediction > 0xFF) {
1350
                    prediction = 0xFF;
1351
                }
1352
                *buf++ = (char)(pixHere[c] - prediction);
1353
            }
1354
        }
1355
    }
1356
}
1357
1358
1359
/*
1360
 * ``Gradient'' filter for other color depths.
1361
 */
1362
1363
#define DEFINE_GRADIENT_FILTER_FUNCTION(bpp)                             \
1364
                                                                         \
1365
static void                                                              \
1366
FilterGradient##bpp(pScreen, buf, fmt, w, h)                             \
1367
    ScreenPtr pScreen;							 \
1368
    CARD##bpp *buf;                                                      \
1369
    rfbPixelFormat *fmt;                                                 \
1370
    int w, h;                                                            \
1371
{                                                                        \
1372
    VNCSCREENPTR(pScreen);						 \
1373
    CARD##bpp pix, diff;                                                 \
1374
    Bool endianMismatch;                                                 \
1375
    int *prevRowPtr;                                                     \
1376
    int maxColor[3], shiftBits[3];                                       \
1377
    int pixHere[3], pixUpper[3], pixLeft[3], pixUpperLeft[3];            \
1378
    int prediction;                                                      \
1379
    int x, y, c;                                                         \
1380
                                                                         \
1381
    memset (prevRowBuf, 0, w * 3 * sizeof(int));                         \
1382
                                                                         \
1383
    endianMismatch = (!pVNC->rfbServerFormat.bigEndian != !fmt->bigEndian);    \
1384
                                                                         \
1385
    maxColor[0] = fmt->redMax;                                           \
1386
    maxColor[1] = fmt->greenMax;                                         \
1387
    maxColor[2] = fmt->blueMax;                                          \
1388
    shiftBits[0] = fmt->redShift;                                        \
1389
    shiftBits[1] = fmt->greenShift;                                      \
1390
    shiftBits[2] = fmt->blueShift;                                       \
1391
                                                                         \
1392
    for (y = 0; y < h; y++) {                                            \
1393
        for (c = 0; c < 3; c++) {                                        \
1394
            pixUpper[c] = 0;                                             \
1395
            pixHere[c] = 0;                                              \
1396
        }                                                                \
1397
        prevRowPtr = prevRowBuf;                                         \
1398
        for (x = 0; x < w; x++) {                                        \
1399
            pix = *buf;                                                  \
1400
            if (endianMismatch) {                                        \
1401
                pix = Swap##bpp(pix);                                    \
1402
            }                                                            \
1403
            diff = 0;                                                    \
1404
            for (c = 0; c < 3; c++) {                                    \
1405
                pixUpperLeft[c] = pixUpper[c];                           \
1406
                pixLeft[c] = pixHere[c];                                 \
1407
                pixUpper[c] = *prevRowPtr;                               \
1408
                pixHere[c] = (int)(pix >> shiftBits[c] & maxColor[c]);   \
1409
                *prevRowPtr++ = pixHere[c];                              \
1410
                                                                         \
1411
                prediction = pixLeft[c] + pixUpper[c] - pixUpperLeft[c]; \
1412
                if (prediction < 0) {                                    \
1413
                    prediction = 0;                                      \
1414
                } else if (prediction > maxColor[c]) {                   \
1415
                    prediction = maxColor[c];                            \
1416
                }                                                        \
1417
                diff |= ((pixHere[c] - prediction) & maxColor[c])        \
1418
                    << shiftBits[c];                                     \
1419
            }                                                            \
1420
            if (endianMismatch) {                                        \
1421
                diff = Swap##bpp(diff);                                  \
1422
            }                                                            \
1423
            *buf++ = diff;                                               \
1424
        }                                                                \
1425
    }                                                                    \
1426
}
1427
1428
DEFINE_GRADIENT_FILTER_FUNCTION(16)
1429
DEFINE_GRADIENT_FILTER_FUNCTION(32)
1430
1431
1432
/*
1433
 * Code to guess if given rectangle is suitable for smooth image
1434
 * compression (by applying "gradient" filter or JPEG coder).
1435
 */
1436
1437
#define JPEG_MIN_RECT_SIZE  4096
1438
1439
#define DETECT_SUBROW_WIDTH    7
1440
#define DETECT_MIN_WIDTH       8
1441
#define DETECT_MIN_HEIGHT      8
1442
1443
static int
1444
DetectSmoothImage (cl, fmt, w, h)
1445
    rfbClientPtr cl;
1446
    rfbPixelFormat *fmt;
1447
    int w, h;
1448
{
1449
    VNCSCREENPTR(cl->pScreen);
1450
    unsigned long avgError;
1451
1452
    if ( pVNC->rfbServerFormat.bitsPerPixel == 8 || fmt->bitsPerPixel == 8 ||
1453
         w < DETECT_MIN_WIDTH || h < DETECT_MIN_HEIGHT ) {
1454
        return 0;
1455
    }
1456
1457
    if (cl->tightQualityLevel != -1) {
1458
        if (w * h < JPEG_MIN_RECT_SIZE) {
1459
            return 0;
1460
        }
1461
    } else {
1462
        if ( rfbTightDisableGradient ||
1463
             w * h < tightConf[cl->tightCompressLevel].gradientMinRectSize ) {
1464
            return 0;
1465
        }
1466
    }
1467
1468
    if (fmt->bitsPerPixel == 32) {
1469
        if (usePixelFormat24) {
1470
            avgError = DetectSmoothImage24(cl, fmt, w, h);
1471
            if (cl->tightQualityLevel != -1) {
1472
                return (avgError < tightConf[cl->tightQualityLevel].jpegThreshold24);
1473
            }
1474
            return (avgError < tightConf[cl->tightCompressLevel].gradientThreshold24);
1475
        } else {
1476
            avgError = DetectSmoothImage32(cl, fmt, w, h);
1477
        }
1478
    } else {
1479
        avgError = DetectSmoothImage16(cl, fmt, w, h);
1480
    }
1481
    if (cl->tightQualityLevel != -1) {
1482
        return (avgError < tightConf[cl->tightQualityLevel].jpegThreshold);
1483
    }
1484
    return (avgError < tightConf[cl->tightCompressLevel].gradientThreshold);
1485
}
1486
1487
static unsigned long
1488
DetectSmoothImage24 (cl, fmt, w, h)
1489
    rfbClientPtr cl;
1490
    rfbPixelFormat *fmt;
1491
    int w, h;
1492
{
1493
    int off;
1494
    int x, y, d, dx, c;
1495
    int diffStat[256];
1496
    int pixelCount = 0;
1497
    int pix, left[3];
1498
    unsigned long avgError;
1499
1500
    /* If client is big-endian, color samples begin from the second
1501
       byte (offset 1) of a 32-bit pixel value. */
1502
    off = (fmt->bigEndian != 0);
1503
1504
    memset(diffStat, 0, 256*sizeof(int));
1505
1506
    y = 0, x = 0;
1507
    while (y < h && x < w) {
1508
        for (d = 0; d < h - y && d < w - x - DETECT_SUBROW_WIDTH; d++) {
1509
            for (c = 0; c < 3; c++) {
1510
                left[c] = (int)tightBeforeBuf[((y+d)*w+x+d)*4+off+c] & 0xFF;
1511
            }
1512
            for (dx = 1; dx <= DETECT_SUBROW_WIDTH; dx++) {
1513
                for (c = 0; c < 3; c++) {
1514
                    pix = (int)tightBeforeBuf[((y+d)*w+x+d+dx)*4+off+c] & 0xFF;
1515
                    diffStat[abs(pix - left[c])]++;
1516
                    left[c] = pix;
1517
                }
1518
                pixelCount++;
1519
            }
1520
        }
1521
        if (w > h) {
1522
            x += h;
1523
            y = 0;
1524
        } else {
1525
            x = 0;
1526
            y += w;
1527
        }
1528
    }
1529
1530
    if (diffStat[0] * 33 / pixelCount >= 95)
1531
        return 0;
1532
1533
    avgError = 0;
1534
    for (c = 1; c < 8; c++) {
1535
        avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c);
1536
        if (diffStat[c] == 0 || diffStat[c] > diffStat[c-1] * 2)
1537
            return 0;
1538
    }
1539
    for (; c < 256; c++) {
1540
        avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c);
1541
    }
1542
    avgError /= (pixelCount * 3 - diffStat[0]);
1543
1544
    return avgError;
1545
}
1546
1547
#define DEFINE_DETECT_FUNCTION(bpp)                                          \
1548
                                                                             \
1549
static unsigned long                                                         \
1550
DetectSmoothImage##bpp (cl, fmt, w, h)                                       \
1551
    rfbClientPtr cl;							     \
1552
    rfbPixelFormat *fmt;                                                     \
1553
    int w, h;                                                                \
1554
{                                                                            \
1555
    VNCSCREENPTR(cl->pScreen);						     \
1556
    Bool endianMismatch;                                                     \
1557
    CARD##bpp pix;                                                           \
1558
    int maxColor[3], shiftBits[3];                                           \
1559
    int x, y, d, dx, c;                                                      \
1560
    int diffStat[256];                                                       \
1561
    int pixelCount = 0;                                                      \
1562
    int sample, sum, left[3];                                                \
1563
    unsigned long avgError;                                                  \
1564
                                                                             \
1565
    endianMismatch = (!pVNC->rfbServerFormat.bigEndian != !fmt->bigEndian);        \
1566
                                                                             \
1567
    maxColor[0] = fmt->redMax;                                               \
1568
    maxColor[1] = fmt->greenMax;                                             \
1569
    maxColor[2] = fmt->blueMax;                                              \
1570
    shiftBits[0] = fmt->redShift;                                            \
1571
    shiftBits[1] = fmt->greenShift;                                          \
1572
    shiftBits[2] = fmt->blueShift;                                           \
1573
                                                                             \
1574
    memset(diffStat, 0, 256*sizeof(int));                                    \
1575
                                                                             \
1576
    y = 0, x = 0;                                                            \
1577
    while (y < h && x < w) {                                                 \
1578
        for (d = 0; d < h - y && d < w - x - DETECT_SUBROW_WIDTH; d++) {     \
1579
            pix = ((CARD##bpp *)tightBeforeBuf)[(y+d)*w+x+d];                \
1580
            if (endianMismatch) {                                            \
1581
                pix = Swap##bpp(pix);                                        \
1582
            }                                                                \
1583
            for (c = 0; c < 3; c++) {                                        \
1584
                left[c] = (int)(pix >> shiftBits[c] & maxColor[c]);          \
1585
            }                                                                \
1586
            for (dx = 1; dx <= DETECT_SUBROW_WIDTH; dx++) {                  \
1587
                pix = ((CARD##bpp *)tightBeforeBuf)[(y+d)*w+x+d+dx];         \
1588
                if (endianMismatch) {                                        \
1589
                    pix = Swap##bpp(pix);                                    \
1590
                }                                                            \
1591
                sum = 0;                                                     \
1592
                for (c = 0; c < 3; c++) {                                    \
1593
                    sample = (int)(pix >> shiftBits[c] & maxColor[c]);       \
1594
                    sum += abs(sample - left[c]);                            \
1595
                    left[c] = sample;                                        \
1596
                }                                                            \
1597
                if (sum > 255)                                               \
1598
                    sum = 255;                                               \
1599
                diffStat[sum]++;                                             \
1600
                pixelCount++;                                                \
1601
            }                                                                \
1602
        }                                                                    \
1603
        if (w > h) {                                                         \
1604
            x += h;                                                          \
1605
            y = 0;                                                           \
1606
        } else {                                                             \
1607
            x = 0;                                                           \
1608
            y += w;                                                          \
1609
        }                                                                    \
1610
    }                                                                        \
1611
                                                                             \
1612
    if ((diffStat[0] + diffStat[1]) * 100 / pixelCount >= 90)                \
1613
        return 0;                                                            \
1614
                                                                             \
1615
    avgError = 0;                                                            \
1616
    for (c = 1; c < 8; c++) {                                                \
1617
        avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c);     \
1618
        if (diffStat[c] == 0 || diffStat[c] > diffStat[c-1] * 2)             \
1619
            return 0;                                                        \
1620
    }                                                                        \
1621
    for (; c < 256; c++) {                                                   \
1622
        avgError += (unsigned long)diffStat[c] * (unsigned long)(c * c);     \
1623
    }                                                                        \
1624
    avgError /= (pixelCount - diffStat[0]);                                  \
1625
                                                                             \
1626
    return avgError;                                                         \
1627
}
1628
1629
DEFINE_DETECT_FUNCTION(16)
1630
DEFINE_DETECT_FUNCTION(32)
1631
1632
1633
/*
1634
 * JPEG compression stuff.
1635
 */
1636
1637
static struct jpeg_destination_mgr jpegDstManager;
1638
static Bool jpegError;
1639
static int jpegDstDataLen;
1640
1641
/**
1642
 * Send the given image rect with jpeg compression.
1643
 * \param buffer  the source image buffer
1644
 * \param w  width of source image in pixels
1645
 * \param h  height of source image in pixels
1646
 * \param quality  jpeg enoding quality
1647
 */
1648
static Bool
1649
SendJpegRect(rfbClientPtr cl, const CARD8 *buffer, int w, int h,
1650
             int quality)
1651
{
1652
    VNCSCREENPTR(cl->pScreen);
1653
    struct jpeg_compress_struct cinfo;
1654
    struct jpeg_error_mgr jerr;
1655
    CARD8 *srcBuf;
1656
    JSAMPROW rowPointer[1];
1657
    int i;
1658
1659
    if (pVNC->rfbServerFormat.bitsPerPixel == 8)
1660
        return SendFullColorRect(cl, w, h);
1661
1662
    srcBuf = (CARD8 *)xalloc(w * 3);
1663
    if (srcBuf == NULL) {
1664
        return SendFullColorRect(cl, w, h);
1665
    }
1666
    rowPointer[0] = srcBuf;
1667
1668
    cinfo.err = jpeg_std_error(&jerr);
1669
    jpeg_create_compress(&cinfo);
1670
1671
    cinfo.image_width = w;
1672
    cinfo.image_height = h;
1673
    cinfo.input_components = 3;
1674
    cinfo.in_color_space = JCS_RGB;
1675
1676
    jpeg_set_defaults(&cinfo);
1677
    jpeg_set_quality(&cinfo, quality, TRUE);
1678
1679
    JpegSetDstManager (&cinfo);
1680
1681
    jpeg_start_compress(&cinfo, TRUE);
1682
1683
    for (i = 0; i < h; i++) {
1684
        PrepareRowForJpeg(cl->pScreen, srcBuf, buffer, i, w);
1685
        jpeg_write_scanlines(&cinfo, rowPointer, 1);
1686
        if (jpegError)
1687
            break;
1688
    }
1689
1690
    if (!jpegError)
1691
        jpeg_finish_compress(&cinfo);
1692
1693
    jpeg_destroy_compress(&cinfo);
1694
    xfree((char *)srcBuf);
1695
1696
    if (jpegError)
1697
        return SendFullColorRect(cl, w, h);
1698
1699
    if (pVNC->ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) {
1700
        if (!rfbSendUpdateBuf(cl))
1701
            return FALSE;
1702
    }
1703
1704
    pVNC->updateBuf[pVNC->ublen++] = (char)(rfbTightJpeg << 4);
1705
    cl->rfbBytesSent[rfbEncodingTight]++;
1706
1707
    return SendCompressedData(cl, jpegDstDataLen);
1708
}
1709
1710
/**
1711
 * Convert pixel data to format needed for jpeg library.
1712
 * \dst  destination buffer (24bpp)
1713
 * \buffer  source buffer (16 or 32bpp)
1714
 * \row  which image row to prepare/convert
1715
 * \width  width of source buffer, in pixels
1716
 */
1717
static void
1718
PrepareRowForJpeg(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer,
1719
                  int row, int width)
1720
{
1721
    VNCSCREENPTR(pScreen);
1722
    if (pVNC->rfbServerFormat.bitsPerPixel == 32) {
1723
        if ( pVNC->rfbServerFormat.redMax == 0xFF &&
1724
             pVNC->rfbServerFormat.greenMax == 0xFF &&
1725
             pVNC->rfbServerFormat.blueMax == 0xFF ) {
1726
            PrepareRowForJpeg24(pScreen, dst, buffer, row, width);
1727
        } else {
1728
            PrepareRowForJpeg32(pScreen, dst, buffer, row, width);
1729
        }
1730
    } else {
1731
        /* 16 bpp assumed. */
1732
        PrepareRowForJpeg16(pScreen, dst, buffer, row, width);
1733
    }
1734
}
1735
1736
/**
1737
 * Src buffer is 32bpp, dst buffer is 24bpp (optimized case).
1738
 */
1739
static void
1740
PrepareRowForJpeg24(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer,
1741
                    int row, int width)
1742
{
1743
    VNCSCREENPTR(pScreen);
1744
    const CARD32 *src = ((const CARD32 *) buffer) + row * width;
1745
    while (width--) {
1746
        CARD32 pix = *src++;
1747
        *dst++ = (CARD8)(pix >> pVNC->rfbServerFormat.redShift);
1748
        *dst++ = (CARD8)(pix >> pVNC->rfbServerFormat.greenShift);
1749
        *dst++ = (CARD8)(pix >> pVNC->rfbServerFormat.blueShift);
1750
    }
1751
}
1752
1753
/**
1754
 * PrepareRowForJpeg16/32: convert 16bpp or 32bpp pixels to 24bpp
1755
 */
1756
#define DEFINE_JPEG_GET_ROW_FUNCTION(bpp)                                   \
1757
                                                                            \
1758
static void                                                                 \
1759
PrepareRowForJpeg##bpp(ScreenPtr pScreen, CARD8 *dst, const CARD8 *buffer,  \
1760
                       int row, int width)                                  \
1761
{                                                                           \
1762
    VNCSCREENPTR(pScreen);						    \
1763
    CARD##bpp *fbptr;                                                       \
1764
    CARD##bpp pix;                                                          \
1765
    int inRed, inGreen, inBlue;                                             \
1766
                                                                            \
1767
    fbptr = ((CARD##bpp *) buffer) + row * width;                           \
1768
                                                                            \
1769
    while (width--) {                                                       \
1770
        pix = *fbptr++;                                                     \
1771
                                                                            \
1772
        inRed = (int)                                                       \
1773
            (pix >> pVNC->rfbServerFormat.redShift   & pVNC->rfbServerFormat.redMax);   \
1774
        inGreen = (int)                                                     \
1775
            (pix >> pVNC->rfbServerFormat.greenShift & pVNC->rfbServerFormat.greenMax); \
1776
        inBlue  = (int)                                                     \
1777
            (pix >> pVNC->rfbServerFormat.blueShift  & pVNC->rfbServerFormat.blueMax);  \
1778
                                                                            \
1779
	*dst++ = (CARD8)((inRed   * 255 + pVNC->rfbServerFormat.redMax / 2) /     \
1780
                         pVNC->rfbServerFormat.redMax);                           \
1781
	*dst++ = (CARD8)((inGreen * 255 + pVNC->rfbServerFormat.greenMax / 2) /   \
1782
                         pVNC->rfbServerFormat.greenMax);                         \
1783
	*dst++ = (CARD8)((inBlue  * 255 + pVNC->rfbServerFormat.blueMax / 2) /    \
1784
                         pVNC->rfbServerFormat.blueMax);                          \
1785
    }                                                                       \
1786
}
1787
1788
DEFINE_JPEG_GET_ROW_FUNCTION(16)
1789
DEFINE_JPEG_GET_ROW_FUNCTION(32)
1790
1791
/*
1792
 * Destination manager implementation for JPEG library.
1793
 */
1794
1795
static void
1796
JpegInitDestination(j_compress_ptr cinfo)
1797
{
1798
    jpegError = FALSE;
1799
    jpegDstManager.next_output_byte = (JOCTET *)tightAfterBuf;
1800
    jpegDstManager.free_in_buffer = (size_t)tightAfterBufSize;
1801
}
1802
1803
static boolean
1804
JpegEmptyOutputBuffer(j_compress_ptr cinfo)
1805
{
1806
    jpegError = TRUE;
1807
    jpegDstManager.next_output_byte = (JOCTET *)tightAfterBuf;
1808
    jpegDstManager.free_in_buffer = (size_t)tightAfterBufSize;
1809
1810
    return TRUE;
1811
}
1812
1813
static void
1814
JpegTermDestination(j_compress_ptr cinfo)
1815
{
1816
    jpegDstDataLen = tightAfterBufSize - jpegDstManager.free_in_buffer;
1817
}
1818
1819
static void
1820
JpegSetDstManager(j_compress_ptr cinfo)
1821
{
1822
    jpegDstManager.init_destination = JpegInitDestination;
1823
    jpegDstManager.empty_output_buffer = JpegEmptyOutputBuffer;
1824
    jpegDstManager.term_destination = JpegTermDestination;
1825
    cinfo->dest = &jpegDstManager;
1826
}
1827
(-)xorg-server-1.4.orig/hw/vnc/translate.c (+502 lines)
Line 0 Link Here
1
/*
2
 * translate.c - translate between different pixel formats
3
 *
4
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
5
 */
6
7
/*
8
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
9
 *
10
 *  This is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  This software is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this software; if not, write to the Free Software
22
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
23
 *  USA.
24
 */
25
#ifdef HAVE_DIX_CONFIG_H
26
#include <dix-config.h>
27
#endif
28
29
30
#include <stdio.h>
31
#include "rfb.h"
32
#if XFREE86VNC
33
#include <micmap.h>
34
#endif
35
36
static void PrintPixelFormat(rfbPixelFormat *pf);
37
static Bool rfbSetClientColourMapBGR233(rfbClientPtr cl);
38
39
Bool rfbEconomicTranslate = FALSE;
40
41
/*
42
 * Some standard pixel formats.
43
 */
44
45
static const rfbPixelFormat BGR233Format = {
46
    8, 8, 0, 1, 7, 7, 3, 0, 3, 6
47
};
48
49
50
/*
51
 * Macro to compare pixel formats.
52
 */
53
54
#define PF_EQ(x,y)							\
55
	((x.bitsPerPixel == y.bitsPerPixel) &&				\
56
	 (x.depth == y.depth) &&					\
57
	 ((x.bigEndian == y.bigEndian) || (x.bitsPerPixel == 8)) &&	\
58
	 (x.trueColour == y.trueColour) &&				\
59
	 (!x.trueColour || ((x.redMax == y.redMax) &&			\
60
			    (x.greenMax == y.greenMax) &&		\
61
			    (x.blueMax == y.blueMax) &&			\
62
			    (x.redShift == y.redShift) &&		\
63
			    (x.greenShift == y.greenShift) &&		\
64
			    (x.blueShift == y.blueShift))))
65
66
#define CONCAT2(a,b) a##b
67
#define CONCAT2E(a,b) CONCAT2(a,b)
68
#define CONCAT4(a,b,c,d) a##b##c##d
69
#define CONCAT4E(a,b,c,d) CONCAT4(a,b,c,d)
70
71
#define OUT 8
72
#include "tableinittctemplate.c"
73
#include "tableinitcmtemplate.c"
74
#define IN 8
75
#include "tabletranstemplate.c"
76
#undef IN
77
#define IN 16
78
#include "tabletranstemplate.c"
79
#undef IN
80
#define IN 32
81
#include "tabletranstemplate.c"
82
#undef IN
83
#undef OUT
84
85
#define OUT 16
86
#include "tableinittctemplate.c"
87
#include "tableinitcmtemplate.c"
88
#define IN 8
89
#include "tabletranstemplate.c"
90
#undef IN
91
#define IN 16
92
#include "tabletranstemplate.c"
93
#undef IN
94
#define IN 32
95
#include "tabletranstemplate.c"
96
#undef IN
97
#undef OUT
98
99
#define OUT 32
100
#include "tableinittctemplate.c"
101
#include "tableinitcmtemplate.c"
102
#define IN 8
103
#include "tabletranstemplate.c"
104
#undef IN
105
#define IN 16
106
#include "tabletranstemplate.c"
107
#undef IN
108
#define IN 32
109
#include "tabletranstemplate.c"
110
#undef IN
111
#undef OUT
112
113
typedef void (*rfbInitTableFnType)(ScreenPtr pScreen, char **table, rfbPixelFormat *in,
114
				   rfbPixelFormat *out);
115
116
rfbInitTableFnType rfbInitTrueColourSingleTableFns[3] = {
117
    rfbInitTrueColourSingleTable8,
118
    rfbInitTrueColourSingleTable16,
119
    rfbInitTrueColourSingleTable32
120
};
121
122
rfbInitTableFnType rfbInitColourMapSingleTableFns[3] = {
123
    rfbInitColourMapSingleTable8,
124
    rfbInitColourMapSingleTable16,
125
    rfbInitColourMapSingleTable32
126
};
127
128
rfbInitTableFnType rfbInitTrueColourRGBTablesFns[3] = {
129
    rfbInitTrueColourRGBTables8,
130
    rfbInitTrueColourRGBTables16,
131
    rfbInitTrueColourRGBTables32
132
};
133
134
rfbTranslateFnType rfbTranslateWithSingleTableFns[3][3] = {
135
    { rfbTranslateWithSingleTable8to8,
136
      rfbTranslateWithSingleTable8to16,
137
      rfbTranslateWithSingleTable8to32 },
138
    { rfbTranslateWithSingleTable16to8,
139
      rfbTranslateWithSingleTable16to16,
140
      rfbTranslateWithSingleTable16to32 },
141
    { rfbTranslateWithSingleTable32to8,
142
      rfbTranslateWithSingleTable32to16,
143
      rfbTranslateWithSingleTable32to32 }
144
};
145
146
rfbTranslateFnType rfbTranslateWithRGBTablesFns[3][3] = {
147
    { rfbTranslateWithRGBTables8to8,
148
      rfbTranslateWithRGBTables8to16,
149
      rfbTranslateWithRGBTables8to32 },
150
    { rfbTranslateWithRGBTables16to8,
151
      rfbTranslateWithRGBTables16to16,
152
      rfbTranslateWithRGBTables16to32 },
153
    { rfbTranslateWithRGBTables32to8,
154
      rfbTranslateWithRGBTables32to16,
155
      rfbTranslateWithRGBTables32to32 }
156
};
157
158
159
160
/*
161
 * rfbTranslateNone is used when no translation is required.
162
 */
163
164
void
165
rfbTranslateNone(ScreenPtr pScreen, char *table, rfbPixelFormat *in, rfbPixelFormat *out,
166
		 unsigned char *optr, int bytesBetweenInputLines,
167
		 int width, int height, int x, int y)
168
{
169
    VNCSCREENPTR(pScreen);
170
    DrawablePtr pDraw = (DrawablePtr)WindowTable[pScreen->myNum];
171
    int truewidth = PixmapBytePad(width, in->bitsPerPixel);
172
173
    if ((x + width > pVNC->width) || truewidth != width * in->bitsPerPixel / 8) {
174
	unsigned char *buffer = malloc(truewidth * height);
175
	unsigned char *buf = buffer;
176
	
177
    	(*pScreen->GetImage)(pDraw, x, y, width, height, ZPixmap, ~0, (char*)buf);
178
	while (height--) {
179
	    memcpy(optr, buf, width * in->bitsPerPixel / 8);
180
	    optr += width * in->bitsPerPixel / 8;
181
	    buf += truewidth;
182
	}
183
	free(buffer);
184
	return;
185
    }
186
187
    (*pScreen->GetImage)(pDraw, x, y, width, height, ZPixmap, ~0, (char*)optr);
188
}
189
190
191
/*
192
 * rfbSetTranslateFunction sets the translation function.
193
 */
194
195
Bool
196
rfbSetTranslateFunction(cl)
197
    rfbClientPtr cl;
198
{
199
    VNCSCREENPTR(cl->pScreen);
200
    rfbLog("Pixel format for client %s:\n",cl->host);
201
    PrintPixelFormat(&cl->format);
202
203
    /*
204
     * Check that bits per pixel values are valid
205
     */
206
207
    if ((pVNC->rfbServerFormat.bitsPerPixel != 8) &&
208
	(pVNC->rfbServerFormat.bitsPerPixel != 16) &&
209
	(pVNC->rfbServerFormat.bitsPerPixel != 32))
210
    {
211
	rfbLog("%s: server bits per pixel not 8, 16 or 32\n",
212
		"rfbSetTranslateFunction");
213
	rfbCloseSock(cl->pScreen, cl->sock);
214
	return FALSE;
215
    }
216
217
    if ((cl->format.bitsPerPixel != 8) &&
218
	(cl->format.bitsPerPixel != 16) &&
219
	(cl->format.bitsPerPixel != 32))
220
    {
221
	rfbLog("%s: client bits per pixel not 8, 16 or 32\n",
222
		"rfbSetTranslateFunction");
223
	rfbCloseSock(cl->pScreen, cl->sock);
224
	return FALSE;
225
    }
226
227
    if (!pVNC->rfbServerFormat.trueColour &&
228
	(pVNC->rfbServerFormat.bitsPerPixel != 8) &&
229
#if XFREE86VNC
230
	(miInstalledMaps[cl->pScreen->myNum]->class == PseudoColor)) {
231
#else
232
	(pVNC->rfbInstalledColormap->class == PseudoColor)) {
233
#endif
234
	rfbLog("rfbSetTranslateFunction: server has colour map "
235
		"but %d-bit - can only cope with 8-bit colour maps\n",
236
		pVNC->rfbServerFormat.bitsPerPixel);
237
	rfbCloseSock(cl->pScreen, cl->sock);
238
	return FALSE;
239
    }
240
241
    if (!cl->format.trueColour &&
242
	(cl->format.bitsPerPixel != 8) &&
243
#if XFREE86VNC
244
	(miInstalledMaps[cl->pScreen->myNum]->class == PseudoColor)) {
245
#else
246
	(pVNC->rfbInstalledColormap->class == PseudoColor) ) {
247
#endif
248
	rfbLog("rfbSetTranslateFunction: client has colour map "
249
		"but %d-bit - can only cope with 8-bit colour maps\n",
250
		cl->format.bitsPerPixel);
251
	rfbCloseSock(cl->pScreen, cl->sock);
252
	return FALSE;
253
    }
254
255
    /*
256
     * bpp is valid, now work out how to translate
257
     */
258
259
    if (!cl->format.trueColour) {
260
261
	/* ? -> colour map */
262
263
	if (!pVNC->rfbServerFormat.trueColour) {
264
265
	    /* colour map -> colour map */
266
267
#if XFREE86VNC
268
	    if (miInstalledMaps[cl->pScreen->myNum]->class == DirectColor) {
269
#else
270
	    if (pVNC->rfbInstalledColormap->class == DirectColor) {
271
#endif
272
	      rfbLog("rfbSetTranslateFunction: client is %d-bit DirectColor,"
273
 		     " client has colour map\n",cl->format.bitsPerPixel);
274
275
	      cl->translateFn = rfbTranslateWithRGBTablesFns
276
			          [pVNC->rfbServerFormat.bitsPerPixel / 16]
277
				  [cl->format.bitsPerPixel / 16];
278
279
  	      (*rfbInitTrueColourRGBTablesFns [cl->format.bitsPerPixel / 16])
280
		   (cl->pScreen, &cl->translateLookupTable,
281
		   &pVNC->rfbServerFormat, &cl->format);
282
283
	      return rfbSetClientColourMap(cl, 0, 0);
284
285
	    /* PseudoColor colormap */
286
287
	    } else {
288
	      rfbLog("rfbSetTranslateFunction: both 8-bit colour map: "
289
		     "no translation needed\n");
290
	      cl->translateFn = rfbTranslateNone;
291
	      return rfbSetClientColourMap(cl, 0, 0);
292
	    }
293
	}
294
295
	/*
296
	 * truecolour -> colour map
297
	 *
298
	 * Set client's colour map to BGR233, then effectively it's
299
	 * truecolour as well
300
	 */
301
302
	if (!rfbSetClientColourMapBGR233(cl))
303
	    return FALSE;
304
305
	cl->format = BGR233Format;
306
    }
307
308
    /* ? -> truecolour */
309
310
    if (!pVNC->rfbServerFormat.trueColour) {
311
312
	/* colour map -> truecolour */
313
314
	rfbLog("rfbSetTranslateFunction: client is %d-bit trueColour,"
315
		" server has colour map\n",cl->format.bitsPerPixel);
316
317
	cl->translateFn = rfbTranslateWithSingleTableFns
318
			      [pVNC->rfbServerFormat.bitsPerPixel / 16]
319
				  [cl->format.bitsPerPixel / 16];
320
321
	return rfbSetClientColourMap(cl, 0, 0);
322
    }
323
324
    /* truecolour -> truecolour */
325
326
    if (PF_EQ(cl->format,pVNC->rfbServerFormat)) {
327
328
	/* client & server the same */
329
330
	rfbLog("  no translation needed\n");
331
	cl->translateFn = rfbTranslateNone;
332
	return TRUE;
333
    }
334
335
    if ((pVNC->rfbServerFormat.bitsPerPixel < 16) ||
336
	(!rfbEconomicTranslate && (pVNC->rfbServerFormat.bitsPerPixel == 16))) {
337
338
	/* we can use a single lookup table for <= 16 bpp */
339
340
	cl->translateFn = rfbTranslateWithSingleTableFns
341
			      [pVNC->rfbServerFormat.bitsPerPixel / 16]
342
				  [cl->format.bitsPerPixel / 16];
343
344
	(*rfbInitTrueColourSingleTableFns
345
	    [cl->format.bitsPerPixel / 16]) (cl->pScreen, 
346
		    			     &cl->translateLookupTable,
347
					     &pVNC->rfbServerFormat, &cl->format);
348
349
    } else {
350
351
	/* otherwise we use three separate tables for red, green and blue */
352
353
	cl->translateFn = rfbTranslateWithRGBTablesFns
354
			      [pVNC->rfbServerFormat.bitsPerPixel / 16]
355
				  [cl->format.bitsPerPixel / 16];
356
357
	(*rfbInitTrueColourRGBTablesFns
358
	    [cl->format.bitsPerPixel / 16]) (cl->pScreen, 
359
		    			     &cl->translateLookupTable,
360
					     &pVNC->rfbServerFormat, &cl->format);
361
    }
362
363
    return TRUE;
364
}
365
366
367
368
/*
369
 * rfbSetClientColourMapBGR233 sets the client's colour map so that it's
370
 * just like an 8-bit BGR233 true colour client.
371
 */
372
373
static Bool
374
rfbSetClientColourMapBGR233(rfbClientPtr cl)
375
{
376
    char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2];
377
    rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf;
378
    CARD16 *rgb = (CARD16 *)(&buf[sz_rfbSetColourMapEntriesMsg]);
379
    int i, len;
380
    int r, g, b;
381
382
    if (cl->format.bitsPerPixel != 8) {
383
	rfbLog("%s: client not 8 bits per pixel\n",
384
		"rfbSetClientColourMapBGR233");
385
	rfbCloseSock(cl->pScreen, cl->sock);
386
	return FALSE;
387
    }
388
389
    scme->type = rfbSetColourMapEntries;
390
391
    scme->firstColour = Swap16IfLE(0);
392
    scme->nColours = Swap16IfLE(256);
393
394
    len = sz_rfbSetColourMapEntriesMsg;
395
396
    i = 0;
397
398
    for (b = 0; b < 4; b++) {
399
	for (g = 0; g < 8; g++) {
400
	    for (r = 0; r < 8; r++) {
401
		rgb[i++] = Swap16IfLE(r * 65535 / 7);
402
		rgb[i++] = Swap16IfLE(g * 65535 / 7);
403
		rgb[i++] = Swap16IfLE(b * 65535 / 3);
404
	    }
405
	}
406
    }
407
408
    len += 256 * 3 * 2;
409
410
    if (WriteExact(cl->sock, buf, len) < 0) {
411
	rfbLogPerror("rfbSetClientColourMapBGR233: write");
412
	rfbCloseSock(cl->pScreen, cl->sock);
413
	return FALSE;
414
    }
415
    return TRUE;
416
}
417
418
419
/*
420
 * rfbSetClientColourMap is called to set the client's colour map.  If the
421
 * client is a true colour client, we simply update our own translation table
422
 * and mark the whole screen as having been modified.
423
 */
424
425
Bool
426
rfbSetClientColourMap(cl, firstColour, nColours)
427
    rfbClientPtr cl;
428
    int firstColour;
429
    int nColours;
430
{
431
    VNCSCREENPTR(cl->pScreen);
432
    BoxRec box;
433
434
    if (nColours == 0) {
435
#if XFREE86VNC
436
	nColours = miInstalledMaps[cl->pScreen->myNum]->pVisual->ColormapEntries;
437
#else
438
	nColours = pVNC->rfbInstalledColormap->pVisual->ColormapEntries;
439
#endif
440
    }
441
442
    if (pVNC->rfbServerFormat.trueColour || !cl->readyForSetColourMapEntries) {
443
	return TRUE;
444
    }
445
446
    if (cl->format.trueColour) {
447
	(*rfbInitColourMapSingleTableFns
448
	    [cl->format.bitsPerPixel / 16]) (cl->pScreen, 
449
		    			     &cl->translateLookupTable,
450
					     &pVNC->rfbServerFormat, &cl->format);
451
452
	REGION_UNINIT(cl->pScreen,&cl->modifiedRegion);
453
	box.x1 = box.y1 = 0;
454
	box.x2 = pVNC->width;
455
	box.y2 = pVNC->height;
456
	REGION_INIT(cl->pScreen,&cl->modifiedRegion,&box,0);
457
458
	return TRUE;
459
    }
460
461
    return rfbSendSetColourMapEntries(cl, firstColour, nColours);
462
}
463
464
465
/*
466
 * rfbSetClientColourMaps sets the colour map for each RFB client.
467
 */
468
469
void
470
rfbSetClientColourMaps(firstColour, nColours)
471
    int firstColour;
472
    int nColours;
473
{
474
    rfbClientPtr cl, nextCl;
475
476
    for (cl = rfbClientHead; cl; cl = nextCl) {
477
	nextCl = cl->next;
478
	rfbSetClientColourMap(cl, firstColour, nColours);
479
    }
480
}
481
482
483
static void
484
PrintPixelFormat(pf)
485
    rfbPixelFormat *pf;
486
{
487
    if (pf->bitsPerPixel == 1) {
488
	rfbLog("  1 bpp, %s sig bit in each byte is leftmost on the screen.\n",
489
	       (pf->bigEndian ? "most" : "least"));
490
    } else {
491
	rfbLog("  %d bpp, depth %d%s\n",pf->bitsPerPixel,pf->depth,
492
	       ((pf->bitsPerPixel == 8) ? ""
493
		: (pf->bigEndian ? ", big endian" : ", little endian")));
494
	if (pf->trueColour) {
495
	    rfbLog("  true colour: max r %d g %d b %d, shift r %d g %d b %d\n",
496
		   pf->redMax, pf->greenMax, pf->blueMax,
497
		   pf->redShift, pf->greenShift, pf->blueShift);
498
	} else {
499
	    rfbLog("  uses a colour map (not true colour).\n");
500
	}
501
    }
502
}
(-)xorg-server-1.4.orig/hw/vnc/vncauth.c (+252 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 */
19
20
/*
21
 * vncauth.c - Functions for VNC password management and authentication.
22
 */
23
#ifdef HAVE_DIX_CONFIG_H
24
#include <dix-config.h>
25
#endif
26
27
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <string.h>
31
#include <sys/types.h>
32
#include <sys/stat.h>
33
#include <time.h>
34
#include <unistd.h>
35
#include <vncauth.h>
36
#include <d3des.h>
37
38
39
/*
40
 * Make sure we call srandom() only once.
41
 */
42
43
static int s_srandom_called = 0;
44
45
/*
46
 * We use a fixed key to store passwords, since we assume that our local
47
 * file system is secure but nonetheless don't want to store passwords
48
 * as plaintext.
49
 */
50
51
static unsigned char s_fixedkey[8] = {23,82,107,6,35,78,88,7};
52
53
54
/*
55
 * Encrypt a password and store it in a file.  Returns 0 if successful,
56
 * 1 if the file could not be written.
57
 *
58
 * NOTE: This function is preserved only for compatibility with the original
59
 * AT&T VNC software.  Use vncEncryptAndStorePasswd2() instead.
60
 */
61
62
int
63
vncEncryptAndStorePasswd(char *passwd, char *fname)
64
{
65
    return (vncEncryptAndStorePasswd2(passwd, NULL, fname) == 0);
66
}
67
68
/*
69
 * Encrypt one or two passwords and store them in a file.  Returns 1 if
70
 * successful, 0 if the file could not be written (note that the original
71
 * vncEncryptAndStorePasswd() function returns inverse values).  The
72
 * passwdViewOnly pointer may be NULL.
73
 *
74
 * NOTE: The file name of "-" denotes stdout.
75
 */
76
77
int
78
vncEncryptAndStorePasswd2(char *passwd, char *passwdViewOnly, char *fname)
79
{
80
    FILE *fp;
81
    int bytesToWrite, bytesWrote;
82
    unsigned char encryptedPasswd[16] = {
83
	0,0,0,0,0,0,0,0,
84
	0,0,0,0,0,0,0,0
85
    };
86
87
    if (strcmp(fname, "-") != 0) {
88
      fp = fopen(fname, "w");
89
      if (fp == NULL) {
90
	return 0;
91
      }
92
      chmod(fname, S_IRUSR|S_IWUSR);
93
    } else {
94
      fp = stdout;
95
    }
96
97
    strncpy((char*)encryptedPasswd, passwd, 8);
98
    if (passwdViewOnly != NULL)
99
	strncpy((char*)encryptedPasswd + 8, passwdViewOnly, 8);
100
101
    /* Do encryption in-place - this way we overwrite our copies of
102
       plaintext passwords. */
103
104
    deskey(s_fixedkey, EN0);
105
    des(encryptedPasswd, encryptedPasswd);
106
    if (passwdViewOnly != NULL)
107
	des(encryptedPasswd + 8, encryptedPasswd + 8);
108
109
    bytesToWrite = (passwdViewOnly == NULL) ? 8 : 16;
110
    bytesWrote = fwrite(encryptedPasswd, 1, bytesToWrite, fp);
111
  
112
    if (fp != stdout) {
113
      fclose(fp);
114
    }
115
    return (bytesWrote == bytesToWrite);
116
}
117
118
119
/*
120
 * Decrypt a password from a file.  Returns a pointer to a newly allocated
121
 * string containing the password or a null pointer if the password could
122
 * not be retrieved for some reason.
123
 *
124
 * NOTE: This function is preserved only for compatibility with the original
125
 * AT&T VNC software.  Use vncDecryptPasswdFromFile2() instead.
126
 */
127
128
char *
129
vncDecryptPasswdFromFile(char *fname)
130
{
131
    char *passwd;
132
133
    passwd = malloc(9);
134
135
    if (passwd != NULL) {
136
	if (vncDecryptPasswdFromFile2(fname, passwd, NULL) == 0) {
137
	    free(passwd);
138
	    passwd = NULL;
139
	}
140
    }
141
142
    return passwd;
143
}
144
145
/*
146
 * Decrypt one or two passwords from a file.  Returns the number of
147
 * passwords read (1, 2, or 0 on error).  On success, the passwords are
148
 * written into buffers passwdFullControl[] and passwdViewOnly[] if
149
 * they are not NULL.  If the pointers to buffers are not NULL, then
150
 * the buffers should be at least of 9 bytes length.
151
 */
152
153
int
154
vncDecryptPasswdFromFile2(char *fname,
155
			  char *passwdFullControl, char *passwdViewOnly)
156
{
157
    FILE *fp;
158
    int i, ch;
159
    unsigned char passwd[16];
160
161
    if (strcmp(fname, "-") != 0) {
162
	if ((fp = fopen(fname,"r")) == NULL)
163
	    return 0;		/* Could not open the file */
164
    } else {
165
	fp = stdin;
166
    }
167
168
    for (i = 0; i < 16; i++) {
169
	ch = getc(fp);
170
	if (ch == EOF)
171
	    break;
172
	passwd[i] = ch;
173
    }
174
175
    if (fp != stdin)
176
	fclose(fp);
177
178
    if (i < 8)
179
	return 0;		/* Could not read eight bytes */
180
181
    deskey(s_fixedkey, DE1);
182
183
    /* Decoding first (full-control) password */
184
    if (passwdFullControl != NULL) {
185
	des(passwd, passwd);
186
	memcpy(passwdFullControl, passwd, 8);
187
	passwdFullControl[8] = '\0';
188
    }
189
190
    /* Decoding second (view-only) password if available */
191
    if (i == 16 && passwdViewOnly != NULL) {
192
	des(&passwd[8], &passwd[8]);
193
	memcpy(passwdViewOnly, &passwd[8], 8);
194
	passwdViewOnly[8] = '\0';
195
    }
196
197
    /* Destroying our copy of clear-text passwords */
198
    memset(passwd, 0, 16);
199
200
    return (i < 16) ? 1 : 2;
201
}
202
203
204
/*
205
 * Generate CHALLENGESIZE random bytes for use in challenge-response
206
 * authentication.
207
 */
208
209
void
210
vncRandomBytes(unsigned char *bytes)
211
{
212
    int i;
213
    unsigned int seed;
214
215
    if (!s_srandom_called) {
216
      seed = (unsigned int)time(0) ^ (unsigned int)getpid();
217
      srandom(seed);
218
      s_srandom_called = 1;
219
    }
220
221
    for (i = 0; i < CHALLENGESIZE; i++) {
222
	bytes[i] = (unsigned char)(random() & 255);    
223
    }
224
}
225
226
227
/*
228
 * Encrypt CHALLENGESIZE bytes in memory using a password.
229
 */
230
231
void
232
vncEncryptBytes(unsigned char *bytes, char *passwd)
233
{
234
    unsigned char key[8];
235
    int i;
236
237
    /* key is simply password padded with nulls */
238
239
    for (i = 0; i < 8; i++) {
240
	if (i < strlen(passwd)) {
241
	    key[i] = passwd[i];
242
	} else {
243
	    key[i] = 0;
244
	}
245
    }
246
247
    deskey(key, EN0);
248
249
    for (i = 0; i < CHALLENGESIZE; i += 8) {
250
	des(bytes+i, bytes+i);
251
    }
252
}
(-)xorg-server-1.4.orig/hw/vnc/vncauth.h (+33 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this software; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 */
19
20
/* 
21
 * vncauth.h - describes the functions provided by the vncauth library.
22
 */
23
24
#define MAXPWLEN 8
25
#define CHALLENGESIZE 16
26
27
extern int vncEncryptAndStorePasswd(char *passwd, char *fname);
28
extern char *vncDecryptPasswdFromFile(char *fname);
29
extern void vncRandomBytes(unsigned char *bytes);
30
extern void vncEncryptBytes(unsigned char *bytes, char *passwd);
31
extern int vncEncryptAndStorePasswd2(char *passwd, char *passwdViewOnly, char *fname);
32
extern int vncDecryptPasswdFromFile2(char *fname, char *passwdFullControl, char *passwdViewOnly);
33
(-)xorg-server-1.4.orig/hw/vnc/vncext.c (+798 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2002 Alan Hourihane.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this software; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 *
19
 *  Author: Alan Hourihane <alanh@fairlite.demon.co.uk>
20
 */
21
#ifdef HAVE_DIX_CONFIG_H
22
#include <dix-config.h>
23
#endif
24
25
26
#include "rfb.h"
27
#include "extnsionst.h"
28
#define _VNC_SERVER
29
#include <X11/extensions/vncstr.h>
30
#ifdef XFree86LOADER
31
#include "xf86Module.h"
32
#endif
33
34
#include <sys/socket.h>
35
#include <netinet/in.h>
36
#include <arpa/inet.h>
37
#include <netdb.h>
38
39
int VncSelectNotify(ClientPtr client, BOOL onoff);
40
void VncExtensionInit(void);
41
42
static int VncErrorBase;  /* first vnc error number */
43
static int VncEventBase;  /* first vnc event number */
44
45
#define USE_ORIG_RES_CODE 0
46
47
#if USE_ORIG_RES_CODE
48
unsigned long VncResourceGeneration = 0;
49
50
static RESTYPE VncNotifyList;
51
52
static XID faked;
53
54
typedef struct _VncNotifyListRec {
55
    struct _VncNotifyListRec *next;
56
    ClientPtr client;
57
} VncNotifyListRec, *VncNotifyListPtr;
58
#endif
59
60
61
/**
62
 * Each X client that uses libVnc to talk to this extension will
63
 * get recorded by one of these records.
64
 */
65
typedef struct _VncClientRec {
66
    ClientPtr client;
67
    struct _VncClientRec *next;
68
    XID fakeID;
69
    RESTYPE res;
70
} VncClientRec, *VncClientRecPtr;
71
72
static VncClientRecPtr ClientsList = NULL;
73
74
75
/**
76
 * Remove client record from list
77
 */
78
static void
79
VncRemoveClientRecord(ClientPtr client)
80
{
81
   /* XXX need 'deleteresource' flag? */
82
    VncClientRecPtr p = ClientsList, prev = NULL;
83
    rfbLog("%s client %p\n", __func__, (void *) client);
84
    while (p) {
85
        if (p->client == client) {
86
            /* remove this one */
87
            if (prev)
88
                prev->next = p->next;
89
            else
90
                ClientsList = p->next;
91
            xfree(p);
92
            return;
93
        }
94
        prev = p;
95
        p = p->next;
96
    }
97
}
98
99
100
/**
101
 * This callback will be called by X's resource manager to delete the
102
 * given resource.  We create one resource for each client.  When X
103
 * deletes the resource, we know the client is going away.
104
 */
105
static int
106
VncDestroyClientResourceCallback(pointer pn, XID id)
107
{
108
    VncClientRecPtr rec = (VncClientRecPtr) pn;
109
    VncRemoveClientRecord(rec->client);
110
    return Success;
111
}
112
113
114
/**
115
 * Add a client record to the list of clients (unless already in list).
116
 * We'll create a new, unique resource for this client.  This is used
117
 * to detect when an X client goes away.
118
 */
119
static void
120
VncSaveClientRecord(ClientPtr client)
121
{
122
    VncClientRecPtr rec = ClientsList;
123
124
    rfbLog("%s saving client %p\n", __func__, (void *) client);
125
126
    /* look if already in list */
127
    while (rec) {
128
        if (rec->client == client) {
129
            return; /* already in list */
130
        }
131
        rec = rec->next;
132
    }
133
134
    /* allocate new client record */
135
    rec = (VncClientRecPtr) xalloc(sizeof(VncClientRec));
136
    if (rec) {
137
        rec->client = client;
138
        rec->fakeID = FakeClientID(client->index);
139
        rec->res = CreateNewResourceType(VncDestroyClientResourceCallback);
140
        if (!AddResource(rec->fakeID, rec->res, rec)) {
141
            xfree(rec);
142
        }
143
144
        /* insert at head of list */
145
        rec->next = ClientsList;
146
        ClientsList = rec;
147
    }
148
}
149
150
151
152
static int
153
ProcVncQueryVersion(ClientPtr client)
154
{
155
    xVncQueryVersionReply 	rep;
156
157
    REQUEST_SIZE_MATCH(xVncQueryVersionReq);
158
    rep.type        	= X_Reply;
159
    rep.sequenceNumber 	= client->sequence;
160
    rep.length         	= 0;
161
    rep.majorVersion  	= VNC_MAJOR_VERSION;
162
    rep.minorVersion  	= VNC_MINOR_VERSION;
163
    if(client->swapped)
164
    {
165
	register char n;
166
    	swaps(&rep.sequenceNumber, n);
167
	swaps(&rep.majorVersion, n);
168
	swaps(&rep.minorVersion, n);
169
    }
170
    (void)WriteToClient(client, SIZEOF(xVncQueryVersionReply),
171
			(char *)&rep);
172
    return (client->noClientException);
173
} /* ProcVncQueryVersion */
174
175
static int
176
ProcVncConnection(ClientPtr client)
177
{
178
    REQUEST(xVncConnectionReq);
179
    xVncConnectionReply 	rep;
180
181
    rfbUserAllow( stuff->sock, stuff->accept );
182
183
    REQUEST_SIZE_MATCH(xVncConnectionReq);
184
    rep.type        	= X_Reply;
185
    rep.sequenceNumber 	= client->sequence;
186
    rep.length         	= 0;
187
    rep.sock  		= 0;
188
    rep.accept  	= 0;
189
    if(client->swapped)
190
    {
191
	register char n;
192
    	swaps(&rep.sequenceNumber, n);
193
	swaps(&rep.sock, n);
194
	swaps(&rep.accept, n);
195
    }
196
    (void)WriteToClient(client, SIZEOF(xVncConnectionReply),
197
			(char *)&rep);
198
    return (client->noClientException);
199
} /* ProcVncConnection */
200
201
static int
202
ProcVncSelectNotify(ClientPtr client)
203
{
204
    REQUEST(xVncSelectNotifyReq);
205
    xVncSelectNotifyReply 	rep;
206
207
    VncSelectNotify(client, stuff->onoff);
208
209
    REQUEST_SIZE_MATCH(xVncSelectNotifyReq);
210
    rep.type        	= X_Reply;
211
    rep.sequenceNumber 	= client->sequence;
212
    rep.length         	= 0;
213
    if(client->swapped)
214
    {
215
	register char n;
216
    	swaps(&rep.sequenceNumber, n);
217
    }
218
    (void)WriteToClient(client, SIZEOF(xVncSelectNotifyReply),
219
			(char *)&rep);
220
    return (client->noClientException);
221
222
}
223
224
static int
225
ProcVncListConnections(ClientPtr client)
226
{
227
    xVncListConnectionsReply 	rep;
228
    rfbClientPtr cl;
229
    int count = 0;
230
    struct in_addr ipaddress;
231
    xVncConnectionListInfo Info;
232
233
    /* count connections */
234
    for (cl = rfbClientHead; cl; cl = cl->next)
235
#ifdef CHROMIUM
236
    /* 
237
     * Fix this, as it should be generic, but we're only using it
238
     * for Chromium at the moment, so we only list the connections
239
     * that have a valid chromium encoding. We should be able to list
240
     * any type requested. FIXME! XXXX
241
     * See furthur down this function too!!!
242
     */
243
	    if (cl->enableChromiumEncoding)
244
#endif
245
	    	count++;
246
247
    REQUEST_SIZE_MATCH(xVncListConnectionsReq);
248
    rep.type        	= X_Reply;
249
    rep.sequenceNumber 	= client->sequence;
250
    rep.count		= count;
251
    rep.length 		= count * sizeof(xVncConnectionListInfo) >> 2;
252
    if(client->swapped)
253
    {
254
	register char n;
255
    	swaps(&rep.sequenceNumber, n);
256
    	swaps(&rep.count, n);
257
    }
258
    (void)WriteToClient(client, SIZEOF(xVncListConnectionsReply),
259
			(char *)&rep);
260
261
    for (cl = rfbClientHead; cl; cl = cl->next) {
262
#ifdef CHROMIUM
263
        /* 
264
         * Fix this, as it should be generic, but we're only using it
265
         * for Chromium at the moment, so we only list the connections
266
         * that have a valid chromium encoding. We should be able to list
267
         * any type requested. FIXME! XXXX
268
         */
269
	if (!cl->enableChromiumEncoding)
270
	    continue;
271
#endif
272
	inet_aton(cl->host, &ipaddress);
273
	memcpy(&Info, &ipaddress, sizeof(struct in_addr));
274
	WriteToClient(client, SIZEOF(xVncConnectionListInfo), (char*)&Info);
275
    }
276
277
    return (client->noClientException);
278
} /* ProcVncListConnections */
279
280
#ifdef CHROMIUM
281
static int
282
ProcVncChromiumStart(ClientPtr client)
283
{
284
    REQUEST(xVncChromiumStartReq);
285
    xVncChromiumStartReply 	rep;
286
287
    rfbSendChromiumStart(stuff->ipaddress, stuff->crServerPort, stuff->mothershipPort);
288
289
    REQUEST_SIZE_MATCH(xVncChromiumStartReq);
290
    rep.type        	= X_Reply;
291
    rep.sequenceNumber 	= client->sequence;
292
    rep.length         	= 0;
293
    if(client->swapped)
294
    {
295
	register char n;
296
    	swaps(&rep.sequenceNumber, n);
297
    }
298
    (void)WriteToClient(client, SIZEOF(xVncChromiumStartReply),
299
			(char *)&rep);
300
    return (client->noClientException);
301
} /* ProcVncChromiumStart */
302
303
static int
304
ProcVncChromiumMonitor(ClientPtr client)
305
{
306
    REQUEST(xVncChromiumMonitorReq);
307
    xVncChromiumMonitorReply 	rep;
308
309
    rfbChromiumMonitorWindowID(stuff->cr_windowid, stuff->windowid);
310
311
    REQUEST_SIZE_MATCH(xVncChromiumMonitorReq);
312
    rep.type        	= X_Reply;
313
    rep.sequenceNumber 	= client->sequence;
314
    rep.length         	= 0;
315
    if(client->swapped)
316
    {
317
	register char n;
318
    	swaps(&rep.sequenceNumber, n);
319
    }
320
    (void)WriteToClient(client, SIZEOF(xVncChromiumMonitorReply),
321
			(char *)&rep);
322
    return (client->noClientException);
323
} /* ProcVncChromiumMonitor */
324
#endif /* CHROMIUM */
325
326
static int
327
ProcVncDispatch(ClientPtr client)
328
{
329
    REQUEST(xReq);
330
331
    switch (stuff->data)
332
    {
333
	case X_VncQueryVersion:
334
	    return ProcVncQueryVersion(client);
335
	case X_VncSelectNotify:
336
	    return ProcVncSelectNotify(client);
337
	case X_VncConnection:
338
	    return ProcVncConnection(client);
339
	case X_VncListConnections:
340
	    return ProcVncListConnections(client);
341
#ifdef CHROMIUM
342
	case X_VncChromiumStart:
343
	    return ProcVncChromiumStart(client);
344
	case X_VncChromiumMonitor:
345
	    return ProcVncChromiumMonitor(client);
346
#endif
347
	default:
348
	    return BadRequest;
349
    }
350
} /* ProcVncDispatch */
351
352
static int
353
SProcVncQueryVersion(ClientPtr client)
354
{
355
    REQUEST(xVncQueryVersionReq);
356
    register char 	n;
357
358
    swaps(&stuff->length, n);
359
    REQUEST_SIZE_MATCH(xVncQueryVersionReq);
360
    swaps(&stuff->majorVersion, n);
361
    swaps(&stuff->minorVersion,n);
362
    return ProcVncQueryVersion(client);
363
} /* SProcVncQueryVersion */
364
365
static int
366
SProcVncSelectNotify(ClientPtr client)
367
{
368
    REQUEST(xVncSelectNotifyReq);
369
    register char 	n;
370
371
    swaps(&stuff->length, n);
372
    REQUEST_SIZE_MATCH(xVncSelectNotifyReq);
373
    return ProcVncSelectNotify(client);
374
} /* SProcVncSelectNotify */
375
376
static int
377
SProcVncListConnections(ClientPtr client)
378
{
379
    REQUEST(xVncListConnectionsReq);
380
    register char 	n;
381
382
    swaps(&stuff->length, n);
383
    REQUEST_SIZE_MATCH(xVncListConnectionsReq);
384
    return ProcVncListConnections(client);
385
} /* SProcVncListConnections */
386
387
#ifdef CHROMIUM
388
static int
389
SProcVncChromiumStart(ClientPtr client)
390
{
391
    REQUEST(xVncChromiumStartReq);
392
    register char 	n;
393
394
    swaps(&stuff->ipaddress, n);
395
    swaps(&stuff->crServerPort, n);
396
    swaps(&stuff->mothershipPort, n);
397
    swaps(&stuff->length, n);
398
    REQUEST_SIZE_MATCH(xVncChromiumStartReq);
399
    return ProcVncChromiumStart(client);
400
} /* SProcVncChromiumStart */
401
402
static int
403
SProcVncChromiumMonitor(ClientPtr client)
404
{
405
    REQUEST(xVncChromiumMonitorReq);
406
    register char 	n;
407
408
    swaps(&stuff->length, n);
409
    swaps(&stuff->windowid, n);
410
    swaps(&stuff->cr_windowid, n);
411
    REQUEST_SIZE_MATCH(xVncChromiumMonitorReq);
412
    return ProcVncChromiumMonitor(client);
413
} /* SProcVncChromiumMonitor */
414
#endif /* CHROMIUM */
415
416
static int
417
SProcVncConnection(ClientPtr client)
418
{
419
    REQUEST(xVncConnectionReq);
420
    register char 	n;
421
422
423
    swaps(&stuff->length, n);
424
    REQUEST_SIZE_MATCH(xVncConnectionReq);
425
    swaps(&stuff->sock, n);
426
    swaps(&stuff->accept,n);
427
    return ProcVncConnection(client);
428
} /* SProcVncConnection */
429
430
static int
431
SProcVncDispatch(ClientPtr client)
432
{
433
    REQUEST(xReq);
434
435
    switch (stuff->data)
436
    {
437
	case X_VncQueryVersion:
438
	    return SProcVncQueryVersion(client);
439
	case X_VncSelectNotify:
440
	    return SProcVncSelectNotify(client);
441
	case X_VncConnection:
442
	    return SProcVncConnection(client);
443
	case X_VncListConnections:
444
	    return SProcVncListConnections(client);
445
#ifdef CHROMIUM
446
	case X_VncChromiumStart:
447
	    return SProcVncChromiumStart(client);
448
	case X_VncChromiumMonitor:
449
	    return SProcVncChromiumMonitor(client);
450
#endif
451
	default:
452
	    return BadRequest;
453
    }
454
} /* SProcVncDispatch */
455
456
static void 
457
SwapVncConnectedEvent(xVncConnectedEvent *from, xVncConnectedEvent *to)
458
{
459
    to->type = from->type;
460
    to->detail = from->detail;
461
    cpswaps(from->sequenceNumber, to->sequenceNumber);
462
    cpswapl(from->connected, to->connected);
463
}
464
465
#ifdef CHROMIUM
466
static void 
467
SwapVncChromiumConnectedEvent(xVncConnectedEvent *from, xVncConnectedEvent *to)
468
{
469
    to->type = from->type;
470
    to->detail = from->detail;
471
    cpswaps(from->sequenceNumber, to->sequenceNumber);
472
    cpswapl(from->connected, to->connected);
473
}
474
#endif
475
476
static void 
477
SwapVncDisconnectedEvent(xVncConnectedEvent *from, xVncConnectedEvent *to)
478
{
479
    to->type = from->type;
480
    to->detail = from->detail;
481
    cpswaps(from->sequenceNumber, to->sequenceNumber);
482
    cpswapl(from->connected, to->connected);
483
}
484
485
int
486
GenerateVncConnectedEvent(int sock)
487
{
488
#if USE_ORIG_RES_CODE
489
    VncNotifyListPtr pn;
490
491
    pn = (VncNotifyListPtr)LookupIDByType(faked, VncNotifyList);
492
#else
493
    VncClientRecPtr pn = ClientsList;
494
#endif
495
496
    while (pn)
497
      {
498
	if (pn->client) 
499
	{
500
    	  xVncConnectedEvent conn;
501
    	  SOCKLEN_T peer_len;
502
    	  struct sockaddr_in peer;
503
504
    	  conn.type = VncEventBase + XVncConnected;
505
    	  conn.sequenceNumber = pn->client->sequence;
506
    	  conn.connected = sock;
507
508
    	  peer_len = sizeof(peer);
509
    	  if (getpeername(sock, (struct sockaddr *) &peer, &peer_len) == -1)
510
		conn.ipaddress = 0;
511
   	  else
512
		conn.ipaddress = (CARD32)peer.sin_addr.s_addr;
513
514
	  (void) TryClientEvents(pn->client, (xEventPtr)&conn, 1, NoEventMask,
515
				 NoEventMask, NullGrab);
516
	}
517
	pn = pn->next;
518
    }
519
520
    return 1;
521
}
522
523
524
525
#ifdef CHROMIUM
526
int
527
GenerateVncChromiumConnectedEvent(int sock)
528
{
529
#if USE_ORIG_RES_CODE
530
    VncNotifyListPtr pn;
531
    pn = (VncNotifyListPtr)LookupIDByType(faked, VncNotifyList);
532
#else
533
    VncClientRecPtr pn = ClientsList;
534
#endif
535
    rfbLog("Enter GenerateVncChromiumConnectedEvent\n");
536
    while (pn)
537
    {
538
	if (pn->client) 
539
	{
540
    	  xVncConnectedEvent conn;
541
    	  SOCKLEN_T peer_len;
542
    	  struct sockaddr_in peer;
543
544
          rfbLog("Sending XVncChromiumConnected to client %p\n",
545
                 (void *) pn->client);
546
547
    	  conn.type = VncEventBase + XVncChromiumConnected;
548
    	  conn.sequenceNumber = pn->client->sequence;
549
    	  conn.connected = sock;
550
551
    	  peer_len = sizeof(peer);
552
    	  if (getpeername(sock, (struct sockaddr *)&peer, &peer_len) == -1)
553
		conn.ipaddress = 0;
554
   	  else
555
		conn.ipaddress = (CARD32)peer.sin_addr.s_addr;
556
557
	  (void) TryClientEvents(pn->client, (xEventPtr)&conn, 1, NoEventMask,
558
				 NoEventMask, NullGrab);
559
	}
560
	pn = pn->next;
561
    }
562
    return 1;
563
}
564
#endif /* CHROMIUM */
565
566
567
int
568
GenerateVncDisconnectedEvent(int sock)
569
{
570
#if USE_ORIG_RES_CODE
571
    VncNotifyListPtr pn;
572
573
    pn = (VncNotifyListPtr)LookupIDByType(faked, VncNotifyList);
574
#else
575
    VncClientRecPtr pn = ClientsList;
576
#endif
577
    rfbLog("GenerateVncDisconnectedEvent\n");
578
    while (pn)
579
    {
580
	if (pn->client) 
581
	{
582
    	  xVncDisconnectedEvent conn;
583
    	  conn.type = VncEventBase + XVncDisconnected;
584
    	  conn.sequenceNumber = pn->client->sequence;
585
    	  conn.connected = sock;
586
	  (void) TryClientEvents(pn->client, (xEventPtr)&conn, 1, NoEventMask,
587
				 NoEventMask, NullGrab);
588
	}
589
	pn = pn->next;
590
    }
591
592
    return 1;
593
}
594
595
static void
596
VncResetProc(ExtensionEntry *extEntry)
597
{
598
} /* VncResetProc */
599
600
601
602
/**
603
 * When the app calls libVnc's XVncSelectNotify() we wind up here.
604
 * Either add or remove 'client' from the VncNotifyList depending on 'onoff'.
605
 */
606
int
607
VncSelectNotify(ClientPtr client, BOOL onoff)
608
{
609
#if USE_ORIG_RES_CODE
610
    VncNotifyListPtr head, newRec, tmp, freeRec = NULL;
611
612
    rfbLog("%s client %p onoff=%d\n", __func__, (void *) client, (int) onoff);
613
    if (!faked)
614
	faked = FakeClientID(client->index);
615
#else
616
    /* ignore onoff param */
617
    VncSaveClientRecord(client);
618
#endif
619
620
#if USE_ORIG_RES_CODE
621
    /* Get the first VncNotifyListPtr */
622
    head = (VncNotifyListPtr) LookupIDByType(faked, VncNotifyList);
623
624
    /* search list for this client */
625
    tmp = head;
626
    while (tmp) {
627
        if (tmp->client == client) {
628
            /* found client! */
629
            if (!onoff)
630
                tmp->client = NULL;
631
            return Success;
632
        }
633
        if (!tmp->client)
634
            freeRec = tmp;  /* save ptr to free record */
635
        tmp = tmp->next;
636
    }
637
638
    /* if we get here, we didn't find client in the list */
639
640
    if (!onoff) {
641
        /* if turning off non-existing client, just return */
642
        return Success;
643
    }
644
645
    /* OK, add new client to list now */
646
647
    if (freeRec) {
648
        /* re-using a free spot */
649
        freeRec->client = client;
650
        return Success;
651
    }
652
653
    /* need to allocate new node */
654
    if (!(newRec = (VncNotifyListPtr)xalloc(sizeof(VncNotifyListRec))))
655
        return BadAlloc;
656
    /* insert at head, just as AddResource() does!!! */
657
    newRec->next = head;
658
    newRec->client = client;
659
    if (!AddResource(faked, VncNotifyList, newRec)) {
660
        xfree(newRec);
661
        return BadAlloc;
662
    }
663
#endif
664
    return Success;
665
}
666
667
668
#if USE_ORIG_RES_CODE
669
static int
670
VncDestroyNotifyList(pointer pn, XID id)
671
{
672
    VncNotifyListPtr cpn = (VncNotifyListPtr) pn;
673
    rfbLog("%s client %p\n", __func__, (void *) cpn->client);
674
    cpn->client = NULL;
675
    return Success;
676
}
677
#endif
678
679
static Bool
680
CreateResourceTypes(void)
681
{
682
#if USE_ORIG_RES_CODE
683
    if (VncResourceGeneration == serverGeneration)
684
        return TRUE;
685
686
    VncResourceGeneration = serverGeneration;
687
688
    if (!(VncNotifyList = CreateNewResourceType(VncDestroyNotifyList))) {
689
        ErrorF("CreateResourceTypes: failed to allocate vnc notify list resource.\n");
690
        return FALSE;
691
    }
692
#endif
693
    return TRUE;
694
}
695
696
697
698
#if XFREE86VNC
699
static unsigned long vncCreateScreenResourcesIndex;
700
static unsigned long vncExtGeneration = 0;
701
extern Bool VNCInit(ScreenPtr pScreen, unsigned char *FBStart);
702
703
/* copied from miscrinit.c */
704
typedef struct
705
{
706
    pointer pbits; /* pointer to framebuffer */
707
    int width;    /* delta to add to a framebuffer addr to move one row down */
708
} miScreenInitParmsRec, *miScreenInitParmsPtr;
709
710
711
static Bool
712
vncCreateScreenResources(ScreenPtr pScreen)
713
{
714
    int ret = TRUE;
715
    CreateScreenResourcesProcPtr CreateScreenResources =
716
        (CreateScreenResourcesProcPtr)
717
        pScreen->devPrivates[vncCreateScreenResourcesIndex].ptr;
718
    miScreenInitParmsPtr pScrInitParms;
719
720
    pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
721
722
    if ( pScreen->CreateScreenResources != vncCreateScreenResources ) {
723
        /* Can't find hook we are hung on */
724
	xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
725
                   "vncCreateScreenResources %p called when not in "
726
                   "pScreen->CreateScreenResources %p n",
727
		   (void *) vncCreateScreenResources,
728
                   (void *) pScreen->CreateScreenResources );
729
    }
730
731
    /* Now do our stuff */
732
    VNCInit(pScreen, pScrInitParms->pbits);
733
734
    /* Unhook this function ... */
735
    pScreen->CreateScreenResources = CreateScreenResources;
736
    pScreen->devPrivates[vncCreateScreenResourcesIndex].ptr = NULL;
737
738
    /* ... and call the previous CreateScreenResources fuction, if any */
739
    if (pScreen->CreateScreenResources) {
740
        ret = (*pScreen->CreateScreenResources)(pScreen);
741
    }
742
743
#ifdef DEBUG
744
    ErrorF("vncCreateScreenResources() returns %d\n", ret);
745
#endif
746
    return ret;
747
}
748
#endif
749
750
751
752
void
753
VncExtensionInit(void)
754
{
755
    ExtensionEntry	*extEntry;
756
757
#if XFREE86VNC
758
    if (vncExtGeneration != serverGeneration) {
759
	unsigned int i;
760
761
	vncExtGeneration = serverGeneration;
762
763
    	if ( ((vncCreateScreenResourcesIndex = AllocateScreenPrivateIndex()) < 0) ||
764
	     ((vncScreenPrivateIndex = AllocateScreenPrivateIndex()) < 0) ||
765
	     ((rfbGCIndex = AllocateGCPrivateIndex()) < 0) )
766
		return;
767
768
    	for (i = 0 ; i < screenInfo.numScreens; i++) 
769
	{
770
      	    screenInfo.screens[i]->devPrivates[vncCreateScreenResourcesIndex].ptr
771
	 		= (void*)(xf86Screens[i]->pScreen->CreateScreenResources);
772
      	    xf86Screens[i]->pScreen->CreateScreenResources = vncCreateScreenResources;
773
    	}
774
775
	gethostname(rfbThisHost, 255);
776
    }
777
#endif
778
779
    if (!CreateResourceTypes())
780
	    return;
781
782
    extEntry = AddExtension(VNC_EXTENSION_NAME,
783
			    XVncNumberEvents, XVncNumberErrors,
784
			    ProcVncDispatch, SProcVncDispatch,
785
                            VncResetProc, StandardMinorOpcode);
786
787
    VncErrorBase = extEntry->errorBase;
788
    VncEventBase = extEntry->eventBase;
789
790
    EventSwapVector[VncEventBase + XVncConnected] =
791
	(EventSwapPtr)SwapVncConnectedEvent;
792
    EventSwapVector[VncEventBase + XVncDisconnected] =
793
	(EventSwapPtr)SwapVncDisconnectedEvent;
794
#ifdef CHROMIUM
795
    EventSwapVector[VncEventBase + XVncChromiumConnected] =
796
	(EventSwapPtr)SwapVncChromiumConnectedEvent;
797
#endif
798
} /* VncExtensionInit */
(-)xorg-server-1.4.orig/hw/vnc/xistubs.c (+323 lines)
Line 0 Link Here
1
/* $Xorg: stubs.c,v 1.4 2001/02/09 02:04:35 xorgcvs Exp $ */
2
3
/************************************************************
4
5
Copyright 1989, 1998  The Open Group
6
7
Permission to use, copy, modify, distribute, and sell this software and its
8
documentation for any purpose is hereby granted without fee, provided that
9
the above copyright notice appear in all copies and that both that
10
copyright notice and this permission notice appear in supporting
11
documentation.
12
13
The above copyright notice and this permission notice shall be included in
14
all copies or substantial portions of the Software.
15
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23
Except as contained in this notice, the name of The Open Group shall not be
24
used in advertising or otherwise to promote the sale, use or other dealings
25
in this Software without prior written authorization from The Open Group.
26
27
Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
28
29
			All Rights Reserved
30
31
Permission to use, copy, modify, and distribute this software and its
32
documentation for any purpose and without fee is hereby granted,
33
provided that the above copyright notice appear in all copies and that
34
both that copyright notice and this permission notice appear in
35
supporting documentation, and that the name of Hewlett-Packard not be
36
used in advertising or publicity pertaining to distribution of the
37
software without specific, written prior permission.
38
39
HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41
HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
45
SOFTWARE.
46
47
********************************************************/
48
/* $XFree86: xc/programs/Xserver/Xi/stubs.c,v 3.3 2001/01/17 22:13:26 dawes Exp $ */
49
50
/*
51
 * stubs.c -- stub routines for the X server side of the XINPUT
52
 * extension.  This file is mainly to be used only as documentation.
53
 * There is not much code here, and you can't get a working XINPUT
54
 * server just using this.
55
 * The Xvfb server uses this file so it will compile with the same
56
 * object files as the real X server for a platform that has XINPUT.
57
 * Xnest could do the same thing.
58
 */
59
#ifdef HAVE_DIX_CONFIG_H
60
#include <dix-config.h>
61
#endif
62
63
64
#define	 NEED_EVENTS
65
#include <X11/X.h>
66
#include <X11/Xproto.h>
67
#include <X11/extensions/XI.h>
68
#include <X11/extensions/XIproto.h>
69
#include "inputstr.h"
70
#include "XIstubs.h"
71
72
/***********************************************************************
73
 *
74
 * Caller:	ProcXChangeKeyboardDevice
75
 *
76
 * This procedure does the implementation-dependent portion of the work
77
 * needed to change the keyboard device.
78
 *
79
 * The X keyboard device has a FocusRec.  If the device that has been 
80
 * made into the new X keyboard did not have a FocusRec, 
81
 * ProcXChangeKeyboardDevice will allocate one for it.
82
 *
83
 * If you do not want clients to be able to focus the old X keyboard
84
 * device, call DeleteFocusClassDeviceStruct to free the FocusRec.
85
 *
86
 * If you support input devices with keys that you do not want to be 
87
 * used as the X keyboard, you need to check for them here and return 
88
 * a BadDevice error.
89
 *
90
 * The default implementation is to do nothing (assume you do want
91
 * clients to be able to focus the old X keyboard).  The commented-out
92
 * sample code shows what you might do if you don't want the default.
93
 *
94
 */
95
96
int
97
ChangeKeyboardDevice (old_dev, new_dev)
98
    DeviceIntPtr	old_dev;
99
    DeviceIntPtr	new_dev;
100
    {
101
    /***********************************************************************
102
     DeleteFocusClassDeviceStruct(old_dev);	 * defined in xchgptr.c *
103
    **********************************************************************/
104
    return BadMatch;
105
    }
106
107
108
/***********************************************************************
109
 *
110
 * Caller:	ProcXChangePointerDevice
111
 *
112
 * This procedure does the implementation-dependent portion of the work
113
 * needed to change the pointer device.
114
 *
115
 * The X pointer device does not have a FocusRec.  If the device that
116
 * has been made into the new X pointer had a FocusRec, 
117
 * ProcXChangePointerDevice will free it.
118
 *
119
 * If you want clients to be able to focus the old pointer device that
120
 * has now become accessible through the input extension, you need to 
121
 * add a FocusRec to it here.
122
 *
123
 * The XChangePointerDevice protocol request also allows the client
124
 * to choose which axes of the new pointer device are used to move 
125
 * the X cursor in the X- and Y- directions.  If the axes are different
126
 * than the default ones, you need to keep track of that here.
127
 *
128
 * If you support input devices with valuators that you do not want to be 
129
 * used as the X pointer, you need to check for them here and return a 
130
 * BadDevice error.
131
 *
132
 * The default implementation is to do nothing (assume you don't want
133
 * clients to be able to focus the old X pointer).  The commented-out
134
 * sample code shows what you might do if you don't want the default.
135
 *
136
 */
137
138
int
139
#if NeedFunctionPrototypes
140
ChangePointerDevice (
141
    DeviceIntPtr	old_dev,
142
    DeviceIntPtr	new_dev,
143
    unsigned char	x,
144
    unsigned char	y)
145
#else
146
ChangePointerDevice (old_dev, new_dev, x, y)
147
    DeviceIntPtr	old_dev, new_dev;
148
    unsigned char	x, y;
149
#endif
150
    {
151
    /***********************************************************************
152
    InitFocusClassDeviceStruct(old_dev);	* allow focusing old ptr*
153
154
    x_axis = x;					* keep track of new x-axis*
155
    y_axis = y;					* keep track of new y-axis*
156
    if (x_axis != 0 || y_axis != 1)
157
	axes_changed = TRUE;			* remember axes have changed*
158
    else
159
	axes_changed = FALSE;
160
    *************************************************************************/
161
    return BadMatch;
162
    }
163
164
/***********************************************************************
165
 *
166
 * Caller:	ProcXCloseDevice
167
 *
168
 * Take care of implementation-dependent details of closing a device.
169
 * Some implementations may actually close the device, others may just
170
 * remove this clients interest in that device.
171
 *
172
 * The default implementation is to do nothing (assume all input devices
173
 * are initialized during X server initialization and kept open).
174
 *
175
 */
176
177
void
178
CloseInputDevice (d, client)
179
    DeviceIntPtr d;
180
    ClientPtr client;
181
    {
182
    }
183
184
/***********************************************************************
185
 *
186
 * Caller:	ProcXListInputDevices
187
 *
188
 * This is the implementation-dependent routine to initialize an input 
189
 * device to the point that information about it can be listed.
190
 * Some implementations open all input devices when the server is first
191
 * initialized, and never close them.  Other implementations open only
192
 * the X pointer and keyboard devices during server initialization,
193
 * and only open other input devices when some client makes an
194
 * XOpenDevice request.  If some other process has the device open, the
195
 * server may not be able to get information about the device to list it.
196
 *
197
 * This procedure should be used by implementations that do not initialize
198
 * all input devices at server startup.  It should do device-dependent
199
 * initialization for any devices not previously initialized, and call
200
 * AddInputDevice for each of those devices so that a DeviceIntRec will be 
201
 * created for them.
202
 *
203
 * The default implementation is to do nothing (assume all input devices
204
 * are initialized during X server initialization and kept open).
205
 * The commented-out sample code shows what you might do if you don't want 
206
 * the default.
207
 *
208
 */
209
210
void
211
AddOtherInputDevices ()
212
    {
213
    /**********************************************************************
214
     for each uninitialized device, do something like: 
215
216
    DeviceIntPtr dev;
217
    DeviceProc deviceProc;
218
    pointer private;
219
220
    dev = (DeviceIntPtr) AddInputDevice(deviceProc, TRUE);
221
    dev->public.devicePrivate = private;
222
    RegisterOtherDevice(dev);
223
    dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
224
    ************************************************************************/
225
226
    }
227
228
/***********************************************************************
229
 *
230
 * Caller:	ProcXOpenDevice
231
 *
232
 * This is the implementation-dependent routine to open an input device.
233
 * Some implementations open all input devices when the server is first
234
 * initialized, and never close them.  Other implementations open only
235
 * the X pointer and keyboard devices during server initialization,
236
 * and only open other input devices when some client makes an
237
 * XOpenDevice request.  This entry point is for the latter type of 
238
 * implementation.
239
 *
240
 * If the physical device is not already open, do it here.  In this case,
241
 * you need to keep track of the fact that one or more clients has the
242
 * device open, and physically close it when the last client that has
243
 * it open does an XCloseDevice.
244
 *
245
 * The default implementation is to do nothing (assume all input devices
246
 * are opened during X server initialization and kept open).
247
 *
248
 */
249
250
void
251
OpenInputDevice (dev, client, status)
252
    DeviceIntPtr dev;
253
    ClientPtr client;
254
    int *status;
255
    {
256
    }
257
258
/****************************************************************************
259
 *
260
 * Caller:	ProcXSetDeviceMode
261
 *
262
 * Change the mode of an extension device.
263
 * This function is used to change the mode of a device from reporting
264
 * relative motion to reporting absolute positional information, and
265
 * vice versa.
266
 * The default implementation below is that no such devices are supported.
267
 *
268
 */
269
270
int
271
SetDeviceMode (client, dev, mode)
272
    register	ClientPtr	client;
273
    DeviceIntPtr dev;
274
    int		mode;
275
    {
276
    return BadMatch;
277
    }
278
279
/****************************************************************************
280
 *
281
 * Caller:	ProcXSetDeviceValuators
282
 *
283
 * Set the value of valuators on an extension input device.
284
 * This function is used to set the initial value of valuators on
285
 * those input devices that are capable of reporting either relative
286
 * motion or an absolute position, and allow an initial position to be set.
287
 * The default implementation below is that no such devices are supported.
288
 *
289
 */
290
291
int
292
SetDeviceValuators (client, dev, valuators, first_valuator, num_valuators)
293
    register	ClientPtr	client;
294
    DeviceIntPtr dev;
295
    int		*valuators;
296
    int		first_valuator;
297
    int		num_valuators;
298
    {
299
    return BadMatch;
300
    }
301
302
/****************************************************************************
303
 *
304
 * Caller:	ProcXChangeDeviceControl
305
 *
306
 * Change the specified device controls on an extension input device.
307
 *
308
 */
309
310
int
311
ChangeDeviceControl (client, dev, control)
312
    register	ClientPtr	client;
313
    DeviceIntPtr dev;
314
    xDeviceCtl	*control;
315
    {
316
    switch (control->control)
317
	{
318
	case DEVICE_RESOLUTION:
319
	    return (BadMatch);
320
	default:
321
	    return (BadMatch);
322
	}
323
    }
(-)xorg-server-1.4.orig/hw/vnc/zlib.c (+310 lines)
Line 0 Link Here
1
/*
2
 * zlib.c
3
 *
4
 * Routines to implement zlib based encoding (deflate).
5
 *
6
 * Modified for XFree86 4.x by Alan Hourihane <alanh@fairlite.demon.co.uk>
7
 */
8
9
/*
10
 *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
11
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
12
 *
13
 *  This is free software; you can redistribute it and/or modify
14
 *  it under the terms of the GNU General Public License as published by
15
 *  the Free Software Foundation; either version 2 of the License, or
16
 *  (at your option) any later version.
17
 *
18
 *  This software is distributed in the hope that it will be useful,
19
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 *  GNU General Public License for more details.
22
 *
23
 *  You should have received a copy of the GNU General Public License
24
 *  along with this software; if not, write to the Free Software
25
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
26
 *  USA.
27
 *
28
 * For the latest source code, please check:
29
 *
30
 * http://www.developVNC.org/
31
 *
32
 * or send email to feedback@developvnc.org.
33
 */
34
#ifdef HAVE_DIX_CONFIG_H
35
#include <dix-config.h>
36
#endif
37
38
39
#include <stdio.h>
40
#include "rfb.h"
41
42
/*
43
 * zlibBeforeBuf contains pixel data in the client's format.
44
 * zlibAfterBuf contains the zlib (deflated) encoding version.
45
 * If the zlib compressed/encoded version is
46
 * larger than the raw data or if it exceeds zlibAfterBufSize then
47
 * raw encoding is used instead.
48
 */
49
50
static int zlibBeforeBufSize = 0;
51
static unsigned char *zlibBeforeBuf = NULL;
52
53
static int zlibAfterBufSize = 0;
54
static unsigned char *zlibAfterBuf = NULL;
55
static int zlibAfterBufLen;
56
57
/*
58
 * rfbSendOneRectEncodingZlib - send a given rectangle using one Zlib
59
 *                              rectangle encoding.
60
 */
61
62
Bool
63
rfbSendOneRectEncodingZlib(cl, x, y, w, h)
64
    rfbClientPtr cl;
65
    int x, y, w, h;
66
{
67
    VNCSCREENPTR(cl->pScreen);
68
    rfbFramebufferUpdateRectHeader rect;
69
    rfbZlibHeader hdr;
70
    int deflateResult;
71
    int previousOut;
72
    int i;
73
    int maxRawSize;
74
    int maxCompSize;
75
76
    maxRawSize = (pVNC->width * pVNC->height
77
                  * (cl->format.bitsPerPixel / 8));
78
79
    if (zlibBeforeBufSize < maxRawSize) {
80
	zlibBeforeBufSize = maxRawSize;
81
	if (zlibBeforeBuf == NULL)
82
	    zlibBeforeBuf = (unsigned char *)xalloc(zlibBeforeBufSize);
83
	else
84
	    zlibBeforeBuf = (unsigned char *)xrealloc(zlibBeforeBuf, zlibBeforeBufSize);
85
    }
86
87
    /* zlib compression is not useful for very small data sets.
88
     * So, we just send these raw without any compression.
89
     */
90
    if (( w * h * (pVNC->bitsPerPixel / 8)) <
91
          VNC_ENCODE_ZLIB_MIN_COMP_SIZE ) {
92
93
        int result;
94
95
        /* The translation function (used also by the in raw encoding)
96
         * requires 4/2/1 byte alignment in the output buffer (which is
97
         * pVNC->updateBuf for the raw encoding) based on the bitsPerPixel of
98
         * the viewer/client.  This prevents SIGBUS errors on some
99
         * architectures like SPARC, PARISC...
100
         */
101
        if (( cl->format.bitsPerPixel > 8 ) &&
102
            ( pVNC->ublen % ( cl->format.bitsPerPixel / 8 )) != 0 ) {
103
            if (!rfbSendUpdateBuf(cl))
104
                return FALSE;
105
        }
106
107
        result = rfbSendRectEncodingRaw(cl, x, y, w, h);
108
109
        return result;
110
111
    }
112
113
    /*
114
     * zlib requires output buffer to be slightly larger than the input
115
     * buffer, in the worst case.
116
     */
117
    maxCompSize = maxRawSize + (( maxRawSize + 99 ) / 100 ) + 12;
118
119
    if (zlibAfterBufSize < maxCompSize) {
120
	zlibAfterBufSize = maxCompSize;
121
	if (zlibAfterBuf == NULL)
122
	    zlibAfterBuf = (unsigned char *)xalloc(zlibAfterBufSize);
123
	else
124
	    zlibAfterBuf = (unsigned char *)xrealloc(zlibAfterBuf, zlibAfterBufSize);
125
    }
126
127
    /* 
128
     * Convert pixel data to client format.
129
     */
130
    (*cl->translateFn)(cl->pScreen, cl->translateLookupTable, 
131
		       &pVNC->rfbServerFormat,
132
		       &cl->format, zlibBeforeBuf,
133
		       pVNC->paddedWidthInBytes, w, h, x, y);
134
135
    cl->compStream.next_in = ( Bytef * )zlibBeforeBuf;
136
    cl->compStream.avail_in = w * h * (cl->format.bitsPerPixel / 8);
137
    cl->compStream.next_out = ( Bytef * )zlibAfterBuf;
138
    cl->compStream.avail_out = maxCompSize;
139
    cl->compStream.data_type = Z_BINARY;
140
141
    /* Initialize the deflation state. */
142
    if ( cl->compStreamInited == FALSE ) {
143
144
        cl->compStream.total_in = 0;
145
        cl->compStream.total_out = 0;
146
        cl->compStream.zalloc = Z_NULL;
147
        cl->compStream.zfree = Z_NULL;
148
        cl->compStream.opaque = Z_NULL;
149
150
        deflateInit2( &(cl->compStream),
151
                        cl->zlibCompressLevel,
152
                        Z_DEFLATED,
153
                        MAX_WBITS,
154
                        MAX_MEM_LEVEL,
155
                        Z_DEFAULT_STRATEGY );
156
        /* deflateInit( &(cl->compStream), Z_BEST_COMPRESSION ); */
157
        /* deflateInit( &(cl->compStream), Z_BEST_SPEED ); */
158
        cl->compStreamInited = TRUE;
159
160
    }
161
162
    previousOut = cl->compStream.total_out;
163
164
    /* Perform the compression here. */
165
    deflateResult = deflate( &(cl->compStream), Z_SYNC_FLUSH );
166
167
    /* Find the total size of the resulting compressed data. */
168
    zlibAfterBufLen = cl->compStream.total_out - previousOut;
169
170
    if ( deflateResult != Z_OK ) {
171
        rfbLog("zlib deflation error: %s\n", cl->compStream.msg);
172
        return FALSE;
173
    }
174
175
    /* Note that it is not possible to switch zlib parameters based on
176
     * the results of the compression pass.  The reason is
177
     * that we rely on the compressor and decompressor states being
178
     * in sync.  Compressing and then discarding the results would
179
     * cause lose of synchronization.
180
     */
181
182
    /* Update statics */
183
    cl->rfbRectanglesSent[rfbEncodingZlib]++;
184
    cl->rfbBytesSent[rfbEncodingZlib] += (sz_rfbFramebufferUpdateRectHeader
185
					 + sz_rfbZlibHeader + zlibAfterBufLen);
186
187
    if (pVNC->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader
188
	> UPDATE_BUF_SIZE)
189
    {
190
	if (!rfbSendUpdateBuf(cl))
191
	    return FALSE;
192
    }
193
194
    rect.r.x = Swap16IfLE(x);
195
    rect.r.y = Swap16IfLE(y);
196
    rect.r.w = Swap16IfLE(w);
197
    rect.r.h = Swap16IfLE(h);
198
    rect.encoding = Swap32IfLE(rfbEncodingZlib);
199
200
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&rect,
201
	   sz_rfbFramebufferUpdateRectHeader);
202
    pVNC->ublen += sz_rfbFramebufferUpdateRectHeader;
203
204
    hdr.nBytes = Swap32IfLE(zlibAfterBufLen);
205
206
    memcpy(&pVNC->updateBuf[pVNC->ublen], (char *)&hdr, sz_rfbZlibHeader);
207
    pVNC->ublen += sz_rfbZlibHeader;
208
209
    for (i = 0; i < zlibAfterBufLen;) {
210
211
	int bytesToCopy = UPDATE_BUF_SIZE - pVNC->ublen;
212
213
	if (i + bytesToCopy > zlibAfterBufLen) {
214
	    bytesToCopy = zlibAfterBufLen - i;
215
	}
216
217
	memcpy(&pVNC->updateBuf[pVNC->ublen], &zlibAfterBuf[i], bytesToCopy);
218
219
	pVNC->ublen += bytesToCopy;
220
	i += bytesToCopy;
221
222
	if (pVNC->ublen == UPDATE_BUF_SIZE) {
223
	    if (!rfbSendUpdateBuf(cl))
224
		return FALSE;
225
	}
226
    }
227
228
    return TRUE;
229
230
}
231
232
233
/*
234
 * rfbSendRectEncodingZlib - send a given rectangle using one or more
235
 *                           Zlib encoding rectangles.
236
 */
237
238
Bool
239
rfbSendRectEncodingZlib(cl, x, y, w, h)
240
    rfbClientPtr cl;
241
    int x, y, w, h;
242
{
243
    VNCSCREENPTR(cl->pScreen);
244
    int  maxLines;
245
    int  linesRemaining;
246
    rfbRectangle partialRect;
247
248
    partialRect.x = x;
249
    partialRect.y = y;
250
    partialRect.w = w;
251
    partialRect.h = h;
252
253
    /* Determine maximum pixel/scan lines allowed per rectangle. */
254
    maxLines = ( ZLIB_MAX_SIZE(w) / w );
255
256
    /* Initialize number of scan lines left to do. */
257
    linesRemaining = h;
258
259
    /* Loop until all work is done. */
260
    while ( linesRemaining > 0 ) {
261
262
        int linesToComp;
263
264
        if ( maxLines < linesRemaining )
265
            linesToComp = maxLines;
266
        else
267
            linesToComp = linesRemaining;
268
269
        partialRect.h = linesToComp;
270
271
        /* Encode (compress) and send the next rectangle. */
272
        if ( ! rfbSendOneRectEncodingZlib( cl,
273
                                           partialRect.x,
274
                                           partialRect.y,
275
                                           partialRect.w,
276
                                           partialRect.h )) {
277
278
            return FALSE;
279
        }
280
281
        /* Technically, flushing the buffer here is not extrememly
282
         * efficient.  However, this improves the overall throughput
283
         * of the system over very slow networks.  By flushing
284
         * the buffer with every maximum size zlib rectangle, we
285
         * improve the pipelining usage of the server CPU, network,
286
         * and viewer CPU components.  Insuring that these components
287
         * are working in parallel actually improves the performance
288
         * seen by the user.
289
         * Since, zlib is most useful for slow networks, this flush
290
         * is appropriate for the desired behavior of the zlib encoding.
291
         */
292
        if (( pVNC->ublen > 0 ) &&
293
            ( linesToComp == maxLines )) {
294
            if (!rfbSendUpdateBuf(cl)) {
295
296
                return FALSE;
297
            }
298
        }
299
300
        /* Update remaining and incremental rectangle location. */
301
        linesRemaining -= linesToComp;
302
        partialRect.y += linesToComp;
303
304
    }
305
306
    return TRUE;
307
308
}
309
310
(-)xorg-server-1.4.orig/hw/xfree86/dixmods/Makefile.am (+10 lines)
Lines 14-19 if DBE Link Here
14
DBEMOD = libdbe.la
14
DBEMOD = libdbe.la
15
endif
15
endif
16
16
17
if XCLIPLIST
18
XCLIPLISTMOD = libxcliplist.la
19
endif
20
17
if AFB
21
if AFB
18
AFBMOD = libafb.la
22
AFBMOD = libafb.la
19
endif
23
endif
Lines 36-41 module_LTLIBRARIES = $(AFBMOD) \ Link Here
36
extsmoduledir = $(moduledir)/extensions
40
extsmoduledir = $(moduledir)/extensions
37
extsmodule_LTLIBRARIES = librecord.la \
41
extsmodule_LTLIBRARIES = librecord.la \
38
			 $(DBEMOD) \
42
			 $(DBEMOD) \
43
                         $(XCLIPLISTMOD) \
39
                         $(GLXMODS) \
44
                         $(GLXMODS) \
40
                         $(XTRAPMOD)
45
                         $(XTRAPMOD)
41
46
Lines 46-51 fontsmodule_LTLIBRARIES = libfreetype.la Link Here
46
AM_CFLAGS = @XORG_CFLAGS@ @DIX_CFLAGS@
51
AM_CFLAGS = @XORG_CFLAGS@ @DIX_CFLAGS@
47
INCLUDES = @XORG_INCS@ \
52
INCLUDES = @XORG_INCS@ \
48
           -I$(top_srcdir)/dbe \
53
           -I$(top_srcdir)/dbe \
54
           -I$(top_srcdir)/xcliplist \
49
           -I$(top_srcdir)/hw/xfree86/loader \
55
           -I$(top_srcdir)/hw/xfree86/loader \
50
           -I$(top_srcdir)/miext/shadow \
56
           -I$(top_srcdir)/miext/shadow \
51
           -I$(top_srcdir)/GL/glx
57
           -I$(top_srcdir)/GL/glx
Lines 70-75 libdbe_la_LDFLAGS = -avoid-version Link Here
70
libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la
76
libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la
71
libdbe_la_SOURCES = dbemodule.c
77
libdbe_la_SOURCES = dbemodule.c
72
78
79
libxcliplist_la_LDFLAGS = -avoid-version
80
libxcliplist_la_LIBADD = $(top_builddir)/xcliplist/libxcliplist.la
81
libxcliplist_la_SOURCES = $(top_srcdir)/xcliplist/cliplistmod.c
82
73
libfb_la_LDFLAGS = -avoid-version
83
libfb_la_LDFLAGS = -avoid-version
74
libfb_la_LIBADD = $(top_builddir)/fb/libfb.la
84
libfb_la_LIBADD = $(top_builddir)/fb/libfb.la
75
libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c
85
libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c
(-)xorg-server-1.4.orig/hw/xfree86/Makefile.am (-2 / +6 lines)
Lines 4-9 if DRI Link Here
4
DRI_SUBDIR = dri
4
DRI_SUBDIR = dri
5
endif
5
endif
6
6
7
if VNC
8
VNC_SUBDIR = vnc
9
endif
10
7
if XF86UTILS
11
if XF86UTILS
8
XF86UTILS_SUBDIR = utils
12
XF86UTILS_SUBDIR = utils
9
endif
13
endif
Lines 21-32 DOC_SUBDIR = doc Link Here
21
SUBDIRS = common ddc dummylib i2c x86emu int10 fbdevhw os-support parser rac \
25
SUBDIRS = common ddc dummylib i2c x86emu int10 fbdevhw os-support parser rac \
22
	  ramdac shadowfb vbe vgahw xaa $(MFB_SUBDIR) $(CFB_SUBDIR) \
26
	  ramdac shadowfb vbe vgahw xaa $(MFB_SUBDIR) $(CFB_SUBDIR) \
23
	  loader scanpci dixmods exa modes \
27
	  loader scanpci dixmods exa modes \
24
	  $(DRI_SUBDIR) $(XF86UTILS_SUBDIR) $(DOC_SUBDIR)
28
	  $(DRI_SUBDIR) $(XF86UTILS_SUBDIR) $(DOC_SUBDIR) $(VNC_SUBDIR)
25
29
26
DIST_SUBDIRS = common ddc dummylib i2c x86emu int10 fbdevhw os-support \
30
DIST_SUBDIRS = common ddc dummylib i2c x86emu int10 fbdevhw os-support \
27
               parser rac ramdac shadowfb vbe vgahw xaa xf1bpp xf4bpp \
31
               parser rac ramdac shadowfb vbe vgahw xaa xf1bpp xf4bpp \
28
               xf8_16bpp xf8_32bpp loader scanpci dixmods dri exa modes \
32
               xf8_16bpp xf8_32bpp loader scanpci dixmods dri exa modes \
29
	       utils doc
33
	       utils doc vnc
30
34
31
bin_PROGRAMS = Xorg
35
bin_PROGRAMS = Xorg
32
36
(-)xorg-server-1.4.orig/hw/xfree86/vnc/Makefile.am (+53 lines)
Line 0 Link Here
1
libvnc_la_LTLIBRARIES = libvnc.la
2
libvnc_la_CFLAGS = -I$(top_srcdir)/hw/xfree86/common \
3
                   -I$(top_srcdir)/hw/xfree86/os-support \
4
                   -I$(top_srcdir)/hw/xfree86/os-support/bus \
5
		   -I$(top_srcdir)/mi \
6
		   -I$(top_srcdir)/render \
7
                   -I$(top_srcdir)/GL/glx \
8
                   -I$(top_srcdir)/GL/include \
9
                   -I$(top_builddir)/GL/include \
10
		   -I@MESA_SOURCE@/include \
11
                   -DHAVE_XORG_CONFIG_H \
12
                   -DXFree86LOADER \
13
                   -DXFREE86VNC=1 \
14
                   -DCHROMIUM=1 \
15
                   @LIBDRM_CFLAGS@ \
16
                   @GL_CFLAGS@ \
17
                   @PIXMAN_CFLAGS@
18
19
#		   @MODULE_DEFINES@
20
#                   @LOADER_DEFINES@
21
22
libvnc_la_LIBADD = -ljpeg -lcrypt
23
libvnc_la_LDFLAGS = -module -avoid-version
24
libvnc_ladir = $(moduledir)/extensions
25
libvnc_la_SOURCES = \
26
	auth.c \
27
	cmap.c \
28
	corre.c \
29
	cursor.c \
30
	cutpaste.c \
31
	d3des.c \
32
	dispcur.c \
33
	draw.c \
34
	hextile.c \
35
	httpd.c \
36
	kbdptr.c \
37
	loginauth.c \
38
	rdp.c \
39
	rfbkeyb.c \
40
	rfbmouse.c \
41
	rfbserver.c \
42
	rre.c \
43
	sockets.c \
44
	sprite.c \
45
	stats.c \
46
	tight.c \
47
	translate.c \
48
	vncInit.c \
49
	vncauth.c \
50
	vncext.c \
51
	zlib.c
52
53
#sdk_HEADERS = vncint.h
(-)xorg-server-1.4.orig/hw/xfree86/vnc/README (+1 lines)
Line 0 Link Here
1
This directory contains the sources for building the vnc.so server extension module.
(-)xorg-server-1.4.orig/hw/xfree86/vnc/vncInit.c (+638 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2002 Alan Hourihane.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this software; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 *
19
 *  Author: Alan Hourihane <alanh@fairlite.demon.co.uk>
20
 */
21
#ifdef HAVE_DIX_CONFIG_H
22
#include <dix-config.h>
23
#endif
24
25
#include <netinet/in.h>
26
#include <time.h>
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <string.h>
30
31
#include "../ramdac/xf86CursorPriv.h"
32
#include "rfb.h"
33
#include "vncint.h"
34
35
#include "xf86.h"
36
#include "xf86_OSproc.h"
37
#include "xf86Resources.h"
38
#include "xf86Version.h"
39
40
int vncScreenPrivateIndex = -1;
41
int rfbGCIndex = -1;
42
int inetdSock = -1;
43
Atom VNC_LAST_CLIENT_ID = 0;
44
Atom VNC_CONNECT = 0;
45
char *desktopName = "x11";
46
char rfbThisHost[256];
47
48
extern void VncExtensionInit(void);
49
50
Bool VNCInit(ScreenPtr pScreen, unsigned char *FBStart);
51
52
#ifndef XFree86LOADER
53
static unsigned long VNCGeneration = 0;
54
#endif
55
static const OptionInfoRec *VNCAvailableOptions(void *unused);
56
static void rfbWakeupHandler (int i, pointer blockData, unsigned long err, pointer pReadmask);
57
58
static Bool vncCursorRealizeCursor(ScreenPtr, CursorPtr);
59
static Bool vncCursorUnrealizeCursor(ScreenPtr, CursorPtr);
60
static void vncCursorSetCursor(ScreenPtr, CursorPtr, int, int);
61
static void vncCursorMoveCursor(ScreenPtr, int, int);
62
static Bool vncDisplayCursor(ScreenPtr, CursorPtr);
63
64
static miPointerSpriteFuncRec vncCursorSpriteFuncs = {
65
   vncCursorRealizeCursor,
66
   vncCursorUnrealizeCursor,
67
   vncCursorSetCursor,
68
   vncCursorMoveCursor
69
};
70
71
/*
72
 * VNC Config options
73
 */
74
75
typedef enum {
76
    OPTION_USEVNC,
77
    OPTION_RFBPORT,
78
    OPTION_HTTPPORT,
79
    OPTION_ALWAYS_SHARED,
80
    OPTION_NEVER_SHARED,
81
    OPTION_DONT_DISCONNECT,
82
    OPTION_HTTPDIR,
83
    OPTION_PASSWD_FILE,
84
    OPTION_USER_ACCEPT,
85
    OPTION_LOCALHOST,
86
    OPTION_INTERFACE,
87
    OPTION_VIEWONLY,
88
    OPTION_LOGIN_AUTH,
89
} VNCOpts;
90
91
static const OptionInfoRec VNCOptions[] = {
92
    {OPTION_USEVNC,		"usevnc",	OPTV_BOOLEAN,	{0}, FALSE },
93
    {OPTION_RFBPORT,		"rfbport",	OPTV_INTEGER, 	{0}, FALSE },
94
    {OPTION_HTTPPORT,		"httpport",	OPTV_INTEGER, 	{0}, FALSE },
95
    {OPTION_ALWAYS_SHARED, 	"alwaysshared", OPTV_BOOLEAN,  	{0}, FALSE },
96
    {OPTION_NEVER_SHARED, 	"nevershared", 	OPTV_BOOLEAN,  	{0}, FALSE },
97
    {OPTION_DONT_DISCONNECT, 	"dontdisconnect", OPTV_BOOLEAN,	{0}, FALSE },
98
    {OPTION_HTTPDIR,		"httpdir",	OPTV_STRING, 	{0}, FALSE },
99
    {OPTION_PASSWD_FILE,	"rfbauth",	OPTV_STRING, 	{0}, FALSE },
100
    {OPTION_USER_ACCEPT,	"useraccept",	OPTV_BOOLEAN, 	{0}, FALSE },
101
    {OPTION_LOCALHOST,		"localhost",	OPTV_BOOLEAN, 	{0}, FALSE },
102
    {OPTION_INTERFACE,		"interface",	OPTV_STRING, 	{0}, FALSE },
103
    {OPTION_VIEWONLY,		"viewonly",	OPTV_BOOLEAN, 	{0}, FALSE },
104
    {OPTION_LOGIN_AUTH,		"loginauth",	OPTV_BOOLEAN, 	{0}, FALSE },
105
    { -1,			NULL,		OPTV_NONE, 	{0}, FALSE }
106
};
107
108
/*ARGSUSED*/
109
static const OptionInfoRec *
110
VNCAvailableOptions(void *unused)
111
{
112
    return (VNCOptions);
113
}
114
115
/*
116
 * rfbLog prints a time-stamped message to the log file (stderr).
117
 */
118
119
void rfbLog(char *format, ...)
120
{
121
    va_list ap;
122
    char buf[256];
123
    time_t clock;
124
125
    time(&clock);
126
    strftime(buf, 255, "%d/%m/%Y %H:%M:%S ", localtime(&clock));
127
    xf86DrvMsgVerb(-1, X_INFO, 1, buf);
128
129
    va_start(ap, format);
130
    xf86VDrvMsgVerb(-1, X_NONE, 1, format, ap);
131
    va_end(ap);
132
}
133
134
void rfbLogPerror(char *str)
135
{
136
    rfbLog("");
137
    perror(str);
138
}
139
140
/*
141
 * Called by vncCreateScreenResources()
142
 */
143
Bool
144
VNCInit(ScreenPtr pScreen, unsigned char *FBStart)
145
{
146
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
147
    VisualPtr visual;
148
    vncScreenPtr pScreenPriv;
149
    OptionInfoPtr options;
150
    char *interface_str = NULL;
151
    miPointerScreenPtr PointPriv;
152
    xf86CursorScreenPtr xf86CursorPriv;
153
#ifdef RENDER
154
    PictureScreenPtr	ps;
155
#endif
156
157
    if (!FBStart)
158
	return FALSE;
159
160
#ifndef XFree86LOADER
161
    if (VNCGeneration != serverGeneration) {
162
	VncExtensionInit();
163
	VNCGeneration = serverGeneration;
164
    }
165
#endif
166
167
    if (!AllocateGCPrivate(pScreen, rfbGCIndex, sizeof(rfbGCRec)))
168
	return FALSE;
169
170
    if (!(pScreenPriv = xalloc(sizeof(vncScreenRec))))
171
	return FALSE;
172
173
    pScreen->devPrivates[vncScreenPrivateIndex].ptr = (pointer)pScreenPriv;
174
175
    options = xnfalloc(sizeof(VNCOptions));
176
    (void)memcpy(options, VNCOptions, sizeof(VNCOptions));
177
    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
178
179
    if (xf86ReturnOptValBool(options, OPTION_USEVNC, FALSE)) {
180
	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VNC enabled\n");
181
    } else {
182
	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VNC disabled\n");
183
	xfree(options);
184
	return FALSE;
185
    }
186
 
187
    pScreenPriv->rfbAuthTries = 0;
188
    pScreenPriv->rfbAuthTooManyTries = FALSE;
189
    pScreenPriv->timer = NULL;
190
    pScreenPriv->udpPort = 0;
191
    pScreenPriv->rfbListenSock = -1;
192
    pScreenPriv->udpSock = -1;
193
    pScreenPriv->udpSockConnected = FALSE;
194
    pScreenPriv->httpListenSock = -1;
195
    pScreenPriv->httpSock = -1;
196
    pScreenPriv->maxFd = 0;
197
    pScreenPriv->rfbAuthPasswdFile = NULL;
198
    pScreenPriv->httpDir = NULL;
199
    pScreenPriv->rfbInstalledColormap = NULL;
200
    pScreenPriv->interface.s_addr = htonl (INADDR_ANY);
201
202
    pScreenPriv->rfbPort = 0;
203
    xf86GetOptValInteger(options, OPTION_RFBPORT, &pScreenPriv->rfbPort);
204
    pScreenPriv->httpPort = 0;
205
    xf86GetOptValInteger(options, OPTION_HTTPPORT, &pScreenPriv->httpPort);
206
    pScreenPriv->rfbAuthPasswdFile = 
207
			xf86GetOptValString(options, OPTION_PASSWD_FILE);
208
    pScreenPriv->httpDir =
209
			xf86GetOptValString(options, OPTION_HTTPDIR);
210
    pScreenPriv->rfbAlwaysShared = FALSE;
211
    xf86GetOptValBool(options, OPTION_ALWAYS_SHARED, 
212
						&pScreenPriv->rfbAlwaysShared);
213
    pScreenPriv->rfbNeverShared = FALSE;
214
    xf86GetOptValBool(options, OPTION_NEVER_SHARED, 
215
						&pScreenPriv->rfbNeverShared);
216
    pScreenPriv->rfbUserAccept = FALSE;
217
    xf86GetOptValBool(options, OPTION_USER_ACCEPT,
218
						&pScreenPriv->rfbUserAccept);
219
    pScreenPriv->rfbViewOnly = FALSE;
220
    xf86GetOptValBool(options, OPTION_VIEWONLY,
221
						&pScreenPriv->rfbViewOnly);
222
    pScreenPriv->rfbDontDisconnect = FALSE;
223
    xf86GetOptValBool(options, OPTION_DONT_DISCONNECT, 
224
						&pScreenPriv->rfbDontDisconnect);
225
    pScreenPriv->loginAuthEnabled = FALSE;
226
    xf86GetOptValBool(options, OPTION_LOGIN_AUTH, 
227
						&pScreenPriv->loginAuthEnabled);
228
229
    if (xf86ReturnOptValBool(options, OPTION_LOCALHOST, FALSE))
230
	pScreenPriv->interface.s_addr = htonl (INADDR_LOOPBACK);
231
232
    interface_str = xf86GetOptValString(options, OPTION_INTERFACE);
233
234
    if (interface_str && pScreenPriv->interface.s_addr == htonl(INADDR_ANY)) {
235
	Bool failed = FALSE;
236
	struct in_addr got;
237
	unsigned long octet;
238
	char *p = interface_str, *end;
239
	int q;
240
241
	for (q = 0; q < 4; q++) {
242
	    octet = strtoul (p, &end, 10);
243
244
	    if (p == end || octet > 255)
245
		failed = TRUE;
246
247
	    if ((q < 3 && *end != '.') ||
248
	        (q == 3 && *end != '\0'))
249
		failed = TRUE;
250
251
	    got.s_addr = (got.s_addr << 8) | octet;
252
	    p = end + 1;
253
	}
254
255
	if (!failed)
256
	    pScreenPriv->interface.s_addr = htonl (got.s_addr);
257
	else
258
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VNC interface option malformed, not using.\n");
259
    }
260
261
    xfree(options);
262
263
    if (!VNC_LAST_CLIENT_ID)
264
    	VNC_LAST_CLIENT_ID = MakeAtom("VNC_LAST_CLIENT_ID",
265
				  strlen("VNC_LAST_CLIENT_ID"), TRUE);
266
    if (!VNC_CONNECT)
267
    	VNC_CONNECT = MakeAtom("VNC_CONNECT", strlen("VNC_CONNECT"), TRUE);
268
269
    rfbInitSockets(pScreen);
270
    if (inetdSock == -1)
271
    	httpInitSockets(pScreen);
272
   
273
#ifdef CORBA
274
    initialiseCORBA(argc, argv, desktopName);
275
#endif
276
277
    pScreenPriv->width = pScrn->virtualX;
278
    pScreenPriv->height = pScrn->virtualY;
279
    pScreenPriv->depth = pScrn->depth;
280
    pScreenPriv->paddedWidthInBytes = PixmapBytePad(pScrn->displayWidth, pScrn->depth);
281
    pScreenPriv->bitsPerPixel = rfbBitsPerPixel(pScrn->depth);
282
    pScreenPriv->pfbMemory = FBStart;
283
    pScreenPriv->oldpfbMemory = FBStart;
284
285
    pScreenPriv->cursorIsDrawn = TRUE;
286
    pScreenPriv->dontSendFramebufferUpdate = FALSE;
287
288
    pScreenPriv->CloseScreen = pScreen->CloseScreen;
289
    pScreenPriv->CreateGC = pScreen->CreateGC;
290
    pScreenPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
291
    pScreenPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
292
    pScreenPriv->CopyWindow = pScreen->CopyWindow;
293
    pScreenPriv->ClearToBackground = pScreen->ClearToBackground;
294
    pScreenPriv->RestoreAreas = pScreen->RestoreAreas;
295
    pScreenPriv->WakeupHandler = pScreen->WakeupHandler;
296
    pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
297
    pScreenPriv->InstallColormap = pScreen->InstallColormap;
298
    pScreenPriv->UninstallColormap = pScreen->UninstallColormap;
299
    pScreenPriv->ListInstalledColormaps = pScreen->ListInstalledColormaps;
300
    pScreenPriv->StoreColors = pScreen->StoreColors;
301
    pScreenPriv->DisplayCursor = pScreen->DisplayCursor;
302
#ifdef CHROMIUM
303
    pScreenPriv->RealizeWindow = pScreen->RealizeWindow;
304
    pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
305
    pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
306
    pScreenPriv->PositionWindow = pScreen->PositionWindow;
307
    pScreenPriv->ResizeWindow = pScreen->ResizeWindow;
308
    pScreenPriv->ClipNotify = pScreen->ClipNotify;
309
#endif
310
#ifdef RENDER
311
    ps = GetPictureScreenIfSet(pScreen);
312
    if (ps)
313
    	pScreenPriv->Composite = ps->Composite;
314
#endif
315
    pScreen->CloseScreen = rfbCloseScreen;
316
    pScreen->CreateGC = rfbCreateGC;
317
    pScreen->PaintWindowBackground = rfbPaintWindowBackground;
318
    pScreen->PaintWindowBorder = rfbPaintWindowBorder;
319
    pScreen->CopyWindow = rfbCopyWindow;
320
    pScreen->ClearToBackground = rfbClearToBackground;
321
    pScreen->RestoreAreas = rfbRestoreAreas;
322
    pScreen->WakeupHandler = rfbWakeupHandler;
323
    pScrn->EnableDisableFBAccess = rfbEnableDisableFBAccess;
324
    pScreen->InstallColormap = rfbInstallColormap;
325
    pScreen->UninstallColormap = rfbUninstallColormap;
326
    pScreen->ListInstalledColormaps = rfbListInstalledColormaps;
327
    pScreen->StoreColors = rfbStoreColors;
328
    pScreen->DisplayCursor = vncDisplayCursor; /* it's defined in here */
329
330
#ifdef CHROMIUM
331
    pScreen->RealizeWindow = rfbRealizeWindow;
332
    pScreen->UnrealizeWindow = rfbUnrealizeWindow;
333
    pScreen->DestroyWindow = rfbDestroyWindow;
334
    pScreen->PositionWindow = rfbPositionWindow;
335
    pScreen->ResizeWindow = rfbResizeWindow;
336
    pScreen->ClipNotify = rfbClipNotify;
337
#endif
338
#ifdef RENDER
339
    if (ps)
340
    	ps->Composite = rfbComposite;
341
#endif
342
343
    for (visual = pScreen->visuals; visual->vid != pScreen->rootVisual; visual++)
344
	;
345
346
    if (!visual) {
347
	ErrorF("rfbScreenInit: couldn't find root visual\n");
348
	return FALSE;
349
    }
350
351
    pScreenPriv->rfbServerFormat.bitsPerPixel = pScrn->bitsPerPixel;
352
    pScreenPriv->rfbServerFormat.depth = pScrn->depth;
353
    pScreenPriv->rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest);
354
    pScreenPriv->rfbServerFormat.trueColour = (visual->class == TrueColor);
355
    if (pScreenPriv->rfbServerFormat.trueColour) {
356
	pScreenPriv->rfbServerFormat.redMax = visual->redMask >> visual->offsetRed;
357
	pScreenPriv->rfbServerFormat.greenMax = visual->greenMask >> visual->offsetGreen;
358
	pScreenPriv->rfbServerFormat.blueMax = visual->blueMask >> visual->offsetBlue;
359
	pScreenPriv->rfbServerFormat.redShift = visual->offsetRed;
360
	pScreenPriv->rfbServerFormat.greenShift = visual->offsetGreen;
361
	pScreenPriv->rfbServerFormat.blueShift = visual->offsetBlue;
362
    } else {
363
	pScreenPriv->rfbServerFormat.redMax
364
	    = pScreenPriv->rfbServerFormat.greenMax 
365
	    = pScreenPriv->rfbServerFormat.blueMax = 0;
366
	pScreenPriv->rfbServerFormat.redShift
367
	    = pScreenPriv->rfbServerFormat.greenShift 
368
	    = pScreenPriv->rfbServerFormat.blueShift = 0;
369
    }
370
371
    PointPriv = pScreen->devPrivates[miPointerScreenIndex].ptr;
372
373
    pScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
374
    PointPriv->spriteFuncs = &vncCursorSpriteFuncs;
375
376
    if (xf86LoaderCheckSymbol("xf86CursorScreenIndex")) {
377
	int *si;
378
379
	si = LoaderSymbol("xf86CursorScreenIndex");
380
381
	if (*si != -1) {
382
    	    xf86CursorPriv = pScreen->devPrivates[*si].ptr;
383
384
	    if (xf86CursorPriv) {
385
		pScreenPriv->UseHWCursor = xf86CursorPriv->CursorInfoPtr->UseHWCursor;
386
		xf86CursorPriv->CursorInfoPtr->UseHWCursor = vncUseHWCursor;
387
#ifdef ARGB_CURSOR
388
		pScreenPriv->UseHWCursorARGB = xf86CursorPriv->CursorInfoPtr->UseHWCursorARGB;
389
		xf86CursorPriv->CursorInfoPtr->UseHWCursorARGB = vncUseHWCursorARGB;
390
#endif
391
		pScreenPriv->SWCursor = &xf86CursorPriv->SWCursor;
392
	    }
393
	}
394
    }
395
396
    return TRUE;
397
}
398
399
/****** miPointerSpriteFunctions *******/
400
401
static Bool
402
vncCursorRealizeCursor(ScreenPtr pScreen, CursorPtr pCurs)
403
{
404
    vncScreenPtr   pScreenPriv = VNCPTR(pScreen);
405
406
    return (*pScreenPriv->spriteFuncs->RealizeCursor)(pScreen, pCurs);
407
}
408
409
static Bool
410
vncCursorUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCurs)
411
{
412
    vncScreenPtr   pScreenPriv = VNCPTR(pScreen);
413
414
    return (*pScreenPriv->spriteFuncs->UnrealizeCursor)(pScreen, pCurs);
415
}
416
417
static void
418
vncCursorSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
419
{
420
    vncScreenPtr   pScreenPriv = VNCPTR(pScreen);
421
422
    pScreenPriv->pCurs = pCurs;
423
424
    /* Without this call, cursor changes only appear in the viewer when
425
     * some other drawing has occured.  Added by BrianP.
426
     */
427
    rfbScheduleUpdate(pScreen);
428
429
#if 0
430
    if (pCurs == NullCursor) {	/* means we're supposed to remove the cursor */
431
	if (pScreenPriv->cursorIsDrawn)
432
	    pScreenPriv->cursorIsDrawn = FALSE;
433
	return;
434
    } 
435
436
    pScreenPriv->cursorIsDrawn = TRUE;
437
#endif
438
439
    (*pScreenPriv->spriteFuncs->SetCursor)(pScreen, pCurs, x, y);
440
}
441
442
static void
443
vncCursorMoveCursor(ScreenPtr pScreen, int x, int y)
444
{
445
    vncScreenPtr   pScreenPriv = VNCPTR(pScreen);
446
    rfbClientPtr cl;
447
448
    for (cl = rfbClientHead; cl ; cl = cl->next) {
449
	if (cl->enableCursorPosUpdates)
450
	    cl->cursorWasMoved = TRUE;
451
    }
452
453
    (*pScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y);
454
}
455
456
Bool
457
vncUseHWCursor(pScreen, pCursor)
458
    ScreenPtr pScreen;
459
    CursorPtr pCursor;
460
{
461
    vncScreenPtr   pScreenPriv = VNCPTR(pScreen);
462
    rfbClientPtr cl;
463
464
    if (!*pScreenPriv->UseHWCursor) {
465
	/* If the driver doesn't have a UseHWCursor function we're
466
	 * basically saying we can have the HWCursor on all the time 
467
	 */
468
    	pScreenPriv->SWCursor = (Bool *)FALSE;
469
	return TRUE;
470
    }
471
472
    pScreenPriv->SWCursor = (Bool *)FALSE;
473
474
    /* If someone's connected, we revert to software cursor */
475
    for (cl = rfbClientHead; cl ; cl = cl->next) {
476
	if (!cl->enableCursorShapeUpdates)
477
	    pScreenPriv->SWCursor = (Bool *)TRUE;
478
    }
479
    
480
    if (pScreenPriv->SWCursor == (Bool *)TRUE)
481
	return FALSE;
482
483
    return (*pScreenPriv->UseHWCursor)(pScreen, pCursor);
484
}
485
486
#ifdef ARGB_CURSOR
487
#include "cursorstr.h"
488
489
Bool
490
vncUseHWCursorARGB(pScreen, pCursor)
491
    ScreenPtr pScreen;
492
    CursorPtr pCursor;
493
{
494
    vncScreenPtr   pScreenPriv = VNCPTR(pScreen);
495
    rfbClientPtr cl;
496
497
    if (!*pScreenPriv->UseHWCursorARGB) {
498
    	pScreenPriv->SWCursor = (Bool *)TRUE;
499
	return FALSE;
500
    }
501
502
    pScreenPriv->SWCursor = (Bool *)FALSE;
503
504
    /* If someone's connected, we revert to software cursor */
505
    for (cl = rfbClientHead; cl ; cl = cl->next) {
506
	if (!cl->enableCursorShapeUpdates)
507
	    pScreenPriv->SWCursor = (Bool *)TRUE;
508
    }
509
    
510
    if (pScreenPriv->SWCursor == (Bool *)TRUE)
511
	return FALSE;
512
513
    return (*pScreenPriv->UseHWCursorARGB)(pScreen, pCursor);
514
}
515
#endif
516
517
static Bool
518
vncDisplayCursor(pScreen, pCursor)
519
    ScreenPtr pScreen;
520
    CursorPtr pCursor;
521
{
522
    vncScreenPtr   pScreenPriv = VNCPTR(pScreen);
523
    rfbClientPtr cl;
524
    Bool ret;
525
526
    pScreen->DisplayCursor = pScreenPriv->DisplayCursor;
527
528
    for (cl = rfbClientHead; cl ; cl = cl->next) {
529
	if (cl->enableCursorShapeUpdates)
530
	    cl->cursorWasChanged = TRUE;
531
    }
532
533
    ret = (*pScreen->DisplayCursor)(pScreen, pCursor);
534
535
    pScreen->DisplayCursor = vncDisplayCursor;
536
537
    return ret;
538
}
539
540
static void
541
rfbWakeupHandler (
542
    int 	i,	
543
    pointer     blockData,
544
    unsigned long err,
545
    pointer     pReadmask
546
){
547
    ScreenPtr      pScreen = screenInfo.screens[i];
548
    vncScreenPtr   pScreenPriv = VNCPTR(pScreen);
549
    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
550
    int sigstate = xf86BlockSIGIO();
551
552
    rfbRootPropertyChange(pScreen); /* Check clipboard */
553
554
    if (pScrn->vtSema) {
555
    	rfbCheckFds(pScreen);
556
    	httpCheckFds(pScreen);
557
#ifdef CORBA
558
    	corbaCheckFds();
559
#endif
560
    } else {
561
    	rfbCheckFds(pScreen);
562
    }
563
564
    xf86UnblockSIGIO(sigstate);		    
565
566
    pScreen->WakeupHandler = pScreenPriv->WakeupHandler;
567
    (*pScreen->WakeupHandler) (i, blockData, err, pReadmask);
568
    pScreen->WakeupHandler = rfbWakeupHandler;
569
}
570
571
#ifdef XFree86LOADER
572
static MODULESETUPPROTO(vncSetup);
573
574
static XF86ModuleVersionInfo vncVersRec =
575
{
576
	"vnc",
577
	"xf4vnc Project, see http://xf4vnc.sf.net (based on modular X.org)",
578
	MODINFOSTRING1,
579
	MODINFOSTRING2,
580
	XORG_VERSION_CURRENT,
581
	1, 1, 0,
582
	ABI_CLASS_EXTENSION,
583
#if 0
584
	ABI_EXTENSION_VERSION,
585
#else
586
        /* Hack to allow module to work with more servers (vs. 0.3 above) */
587
        SET_ABI_VERSION(0, 2),
588
#endif
589
	MOD_CLASS_EXTENSION,
590
	{0,0,0,0}
591
};
592
593
XF86ModuleData vncModuleData = {
594
    &vncVersRec,           /* vers */
595
    vncSetup,              /* ModuleSetupProc */
596
    NULL                   /* ModuleTearDownProc */
597
};
598
599
ModuleInfoRec VNC = {
600
    1,                     /* moduleVersion */
601
    "VNC",                 /* moduleName */
602
    NULL,                  /* module pointer */
603
    0,                     /* refCount */
604
    VNCAvailableOptions,   /* function returning array of OptionsInfoRec */
605
};
606
607
ExtensionModule vncExtensionModule = {
608
        VncExtensionInit,  /* initFunc */
609
        "VNC",             /* name */
610
        NULL,              /* disablePtr */
611
        NULL,              /* setupFunc */
612
        NULL               /* initDependencies */
613
};
614
615
616
/*ARGSUSED*/
617
static pointer
618
vncSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
619
{
620
    static Bool Initialised = FALSE;
621
622
    if (!Initialised) {
623
	Initialised = TRUE;
624
#ifndef REMOVE_LOADER_CHECK_MODULE_INFO
625
	if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
626
#endif
627
	xf86AddModuleInfo(&VNC, Module);
628
    }
629
630
    LoadExtension(&vncExtensionModule, FALSE);
631
    /* add mouse/kbd input drivers */
632
    vncInitMouse();
633
    vncInitKeyb();
634
    xf86Msg(X_INFO, "Ignore errors regarding the loading of the rfbmouse & rfbkeyb drivers\n");
635
636
    return (pointer)TRUE;
637
}
638
#endif
(-)xorg-server-1.4.orig/hw/xfree86/vnc/vncint.h (+154 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2002 Alan Hourihane.  All Rights Reserved.
3
 *
4
 *  This is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This software is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this software; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17
 *  USA.
18
 *
19
 *  Author: Alan Hourihane <alanh@fairlite.demon.co.uk>
20
 */
21
22
#ifndef _VNC_H_
23
#define _VNC_H_
24
25
#include <xorg/xf86Cursor.h>
26
/*#include <xf86CursorPriv.h>*/
27
28
extern int vncScreenPrivateIndex;
29
30
#define VNCPTR(pScreen)\
31
   (vncScreenPtr)((pScreen)->devPrivates[vncScreenPrivateIndex].ptr)
32
33
typedef struct {
34
    int			rfbPort;
35
    int			rdpPort;
36
    int			udpPort;
37
    int			rfbListenSock;
38
    int			rdpListenSock;
39
    int			udpSock;
40
    int			httpPort;
41
    int			httpListenSock;
42
    int			httpSock;
43
    char *		httpDir;
44
    char		buf[HTTP_BUF_SIZE];
45
    Bool		udpSockConnected;
46
    char *		rfbAuthPasswdFile;
47
    size_t		buf_filled;
48
    int			maxFd;
49
    fd_set		allFds;
50
    unsigned char *	oldpfbMemory;
51
    Bool		rfbAlwaysShared;
52
    Bool		rfbNeverShared;
53
    Bool		rfbDontDisconnect;
54
    Bool		rfbUserAccept;
55
    Bool		rfbViewOnly;
56
    unsigned char *	pfbMemory;
57
    int 		paddedWidthInBytes;
58
    ColormapPtr 	rfbInstalledColormap;
59
    ColormapPtr		savedColormap;
60
    rfbPixelFormat	rfbServerFormat;
61
    Bool		rfbAuthTooManyTries;
62
    int			rfbAuthTries;
63
    Bool		loginAuthEnabled;
64
    struct in_addr	interface;
65
    OsTimerPtr 		timer;
66
    unsigned char 	updateBuf[UPDATE_BUF_SIZE];
67
    int 		ublen;
68
    int 		width;
69
    int 		height;
70
    int 		depth;
71
    int 		bitsPerPixel;
72
73
    /* The following two members are used to minimise the amount of unnecessary
74
       drawing caused by cursor movement.  Whenever any drawing affects the
75
       part of the screen where the cursor is, the cursor is removed first and
76
       then the drawing is done (this is what the sprite routines test for).
77
       Afterwards, however, we do not replace the cursor, even when the cursor
78
       is logically being moved across the screen.  We only draw the cursor
79
       again just as we are about to send the client a framebuffer update.
80
81
       We need to be careful when removing and drawing the cursor because of
82
       their relationship with the normal drawing routines.  The drawing
83
       routines can invoke the cursor routines, but also the cursor routines
84
       themselves end up invoking drawing routines.
85
86
       Removing the cursor (rfbSpriteRemoveCursor) is eventually achieved by
87
       doing a CopyArea from a pixmap to the screen, where the pixmap contains
88
       the saved contents of the screen under the cursor.  Before doing this,
89
       however, we set cursorIsDrawn to FALSE.  Then, when CopyArea is called,
90
       it sees that cursorIsDrawn is FALSE and so doesn't feel the need to
91
       (recursively!) remove the cursor before doing it.
92
93
       Putting up the cursor (rfbSpriteRestoreCursor) involves a call to
94
       PushPixels.  While this is happening, cursorIsDrawn must be FALSE so
95
       that PushPixels doesn't think it has to remove the cursor first.
96
       Obviously cursorIsDrawn is set to TRUE afterwards.
97
98
       Another problem we face is that drawing routines sometimes cause a
99
       framebuffer update to be sent to the RFB client.  When the RFB client is
100
       already waiting for a framebuffer update and some drawing to the
101
       framebuffer then happens, the drawing routine sees that the client is
102
       ready, so it calls rfbSendFramebufferUpdate.  If the cursor is not drawn
103
       at this stage, it must be put up, and so rfbSpriteRestoreCursor is
104
       called.  However, if the original drawing routine was actually called
105
       from within rfbSpriteRestoreCursor or rfbSpriteRemoveCursor we don't
106
       want this to happen.  So both the cursor routines set
107
       dontSendFramebufferUpdate to TRUE, and all the drawing routines check
108
       this before calling rfbSendFramebufferUpdate. */
109
110
    Bool cursorIsDrawn;		    /* TRUE if the cursor is currently drawn */
111
    Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the
112
				       cursor */
113
114
    /* wrapped screen functions */
115
116
    CloseScreenProcPtr			CloseScreen;
117
    CreateGCProcPtr			CreateGC;
118
    PaintWindowBackgroundProcPtr	PaintWindowBackground;
119
    PaintWindowBorderProcPtr		PaintWindowBorder;
120
    CopyWindowProcPtr			CopyWindow;
121
    ClearToBackgroundProcPtr		ClearToBackground;
122
    RestoreAreasProcPtr			RestoreAreas;
123
    ScreenWakeupHandlerProcPtr 		WakeupHandler;
124
    InstallColormapProcPtr		InstallColormap;
125
    UninstallColormapProcPtr		UninstallColormap;
126
    ListInstalledColormapsProcPtr 	ListInstalledColormaps;
127
    StoreColorsProcPtr			StoreColors;
128
    xf86EnableDisableFBAccessProc	*EnableDisableFBAccess;
129
    miPointerSpriteFuncPtr		spriteFuncs;
130
    DisplayCursorProcPtr		DisplayCursor;
131
    CursorPtr				pCurs;
132
    Bool				(*UseHWCursor)(ScreenPtr, CursorPtr);
133
    Bool				(*UseHWCursorARGB)(ScreenPtr, CursorPtr);
134
    Bool				*SWCursor;
135
#ifdef CHROMIUM
136
    RealizeWindowProcPtr		RealizeWindow;
137
    UnrealizeWindowProcPtr		UnrealizeWindow;
138
    DestroyWindowProcPtr		DestroyWindow;
139
    ResizeWindowProcPtr			ResizeWindow;
140
    PositionWindowProcPtr		PositionWindow;
141
    ClipNotifyProcPtr			ClipNotify;
142
#endif
143
#ifdef RENDER
144
    CompositeProcPtr			Composite;
145
#endif
146
147
} vncScreenRec, *vncScreenPtr;
148
149
extern Bool vncUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
150
extern Bool vncUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
151
extern void rfbEnableDisableFBAccess (int index, Bool enable);
152
153
#endif /* _VNC_H_ */
154
(-)xorg-server-1.4.orig/Makefile.am (+5 lines)
Lines 30-35 if DBE Link Here
30
DBE_DIR=dbe
30
DBE_DIR=dbe
31
endif
31
endif
32
32
33
if XCLIPLIST
34
XCLIPLIST_DIR=xcliplist
35
endif
36
33
SUBDIRS = \
37
SUBDIRS = \
34
	doc \
38
	doc \
35
	include \
39
	include \
Lines 54-59 SUBDIRS = \ Link Here
54
	$(XTRAP_DIR) \
58
	$(XTRAP_DIR) \
55
	$(COMPOSITE_DIR) \
59
	$(COMPOSITE_DIR) \
56
	$(GLX_DIR) \
60
	$(GLX_DIR) \
61
	$(XCLIPLIST_DIR) \
57
	exa \
62
	exa \
58
	config \
63
	config \
59
	hw
64
	hw
(-)xorg-server-1.4.orig/mi/miinitext.c (+12 lines)
Lines 79-84 SOFTWARE. Link Here
79
#undef XF86VIDMODE
79
#undef XF86VIDMODE
80
#endif
80
#endif
81
81
82
#ifdef VNCSERVER
83
#undef COMPOSITE
84
#undef DAMAGE
85
#undef DBE
86
#undef RANDR
87
#undef XF86MISC
88
#undef XFreeXDGA
89
#undef XF86DRI
90
#undef XF86VIDMODE
91
#undef XFIXES
92
#endif
93
82
#include "misc.h"
94
#include "misc.h"
83
#include "extension.h"
95
#include "extension.h"
84
#include "micmap.h"
96
#include "micmap.h"
(-)xorg-server-1.4.orig/xcliplist/cliplist.c (+128 lines)
Line 0 Link Here
1
/*
2
 * Server-side code for the Xcliplist extension
3
 */
4
5
#if HAVE_DIX_CONFIG_H
6
#include "dix-config.h"
7
#endif
8
9
#include <stdio.h>
10
#include <assert.h>
11
12
#include "dixstruct.h"
13
#include "extnsionst.h"
14
#include "windowstr.h"
15
16
#define _XCLIPLIST_SERVER_
17
#include <X11/extensions/Xclipliststr.h>
18
19
20
static int XClipListErrorBase;
21
static unsigned char XClipListReqCode = 0;
22
23
static void
24
XClipListResetProc(ExtensionEntry* extEntry)
25
{
26
   (void)extEntry;
27
}
28
29
static int
30
ProcXClipListQueryVersion(ClientPtr client)
31
{
32
   xXClipListQueryVersionReply rep;
33
34
   REQUEST_SIZE_MATCH(xXClipListQueryVersionReq);
35
   rep.type = X_Reply;
36
   rep.length = 0;
37
   rep.sequenceNumber = client->sequence;
38
   rep.majorVersion = XCLIPLIST_MAJOR_VERSION;
39
   rep.minorVersion = XCLIPLIST_MINOR_VERSION;
40
   rep.patchVersion = XCLIPLIST_PATCH_VERSION;
41
42
   WriteToClient(client, sizeof(xXClipListQueryVersionReply), (char *)&rep);
43
   return (client->noClientException);
44
}
45
46
static int
47
ProcXGetClipList(ClientPtr client)
48
{
49
   xXGetClipListReply	rep;
50
   WindowPtr pWin;
51
   int i;
52
   BoxPtr pClipRects = NULL;
53
   short xorig, yorig;
54
   REQUEST(xXGetClipListReq);
55
   REQUEST_SIZE_MATCH(xXGetClipListReq);
56
57
   rep.type = X_Reply;
58
   rep.length = 0;
59
   rep.sequenceNumber = client->sequence;
60
61
   if(!(pWin = (WindowPtr)LOOKUP_DRAWABLE(stuff->windowid, client) ))
62
    {
63
      client->errorValue = stuff->windowid;
64
      return (BadWindow);
65
    }
66
67
   rep.num_entries = REGION_NUM_RECTS(&pWin->clipList);
68
69
   WriteToClient(client, sizeof(xXGetClipListReply), (char *)&rep);
70
71
   pClipRects = REGION_RECTS(&pWin->clipList);
72
73
   xorig = pWin->drawable.x;
74
   yorig = pWin->drawable.y;
75
76
   for (i = 0; i < rep.num_entries; i++) {
77
      BoxRec box;
78
      /* translate clip rect from screen coords to window coords */
79
      box.x1 = pClipRects[i].x1 - xorig;
80
      box.y1 = pClipRects[i].y1 - yorig;
81
      box.x2 = pClipRects[i].x2 - xorig;
82
      box.y2 = pClipRects[i].y2 - yorig;
83
      /*memcpy(&box, &pClipRects[i], sizeof(BoxRec));*/
84
      WriteToClient(client, sizeof(BoxRec), (char *)&box);
85
   }
86
87
   return (client->noClientException);
88
}
89
90
static int
91
ProcXClipListDispatch (ClientPtr	client)
92
{
93
   REQUEST(xReq);
94
95
   switch (stuff->data) {
96
   case X_XClipListQueryVersion:
97
      return ProcXClipListQueryVersion(client);
98
   case X_XGetClipList:
99
      return ProcXGetClipList(client);
100
   default:
101
      return BadRequest;
102
   }
103
}
104
105
static int
106
SProcXClipListDispatch (ClientPtr	client)
107
{
108
   REQUEST(xReq);
109
   (void)stuff;
110
   return XClipListErrorBase + XClipListClientNotLocal;
111
}
112
113
void
114
XClipListExtensionInit(void)
115
{
116
   ExtensionEntry* extEntry;
117
118
   if ((extEntry = AddExtension(XCLIPLISTNAME,
119
				XClipListNumberEvents,
120
				XClipListNumberErrors,
121
				ProcXClipListDispatch,
122
				SProcXClipListDispatch,
123
				XClipListResetProc,
124
				StandardMinorOpcode))) {
125
      XClipListReqCode = (unsigned char)extEntry->base;
126
      XClipListErrorBase = extEntry->errorBase;
127
   }
128
}
(-)xorg-server-1.4.orig/xcliplist/cliplistmod.c (+46 lines)
Line 0 Link Here
1
2
#include "xorg/xf86Module.h"
3
4
extern Bool noTestExtensions;
5
6
static MODULESETUPPROTO(xcliplistSetup);
7
8
extern void XClipListExtensionInit(INITARGS);
9
10
ExtensionModule xcliplistExt = {
11
    XClipListExtensionInit,
12
    "XClipList",
13
    &noTestExtensions,
14
    NULL,
15
    NULL
16
};
17
18
static XF86ModuleVersionInfo VersRec = {
19
	"XClipList",
20
	MODULEVENDORSTRING,
21
	MODINFOSTRING1,
22
	MODINFOSTRING2,
23
        XF86_VERSION_CURRENT, /* XXX fix? */
24
	1, 13, 0,
25
	ABI_CLASS_EXTENSION,
26
#if 0
27
	ABI_EXTENSION_VERSION,
28
#else
29
        /* Hack to allow module to work with more servers (vs. 0.3 above) */
30
        SET_ABI_VERSION(0, 2),
31
#endif
32
	MOD_CLASS_EXTENSION,
33
	{0,0,0,0}
34
};
35
36
XF86ModuleData xcliplistModuleData = { &VersRec, xcliplistSetup, NULL };
37
38
static pointer
39
xcliplistSetup(pointer module, pointer opts, int *errmaj, int *errmin)
40
{
41
    LoadExtension(&xcliplistExt, FALSE);
42
43
    /* Need a non-NULL return value to indicate success */
44
    return (pointer)1;
45
}
46
(-)xorg-server-1.4.orig/xcliplist/Makefile.am (+18 lines)
Line 0 Link Here
1
#noinst_LTLIBRARIES = libxcliplist.la
2
libxcliplist_la_LTLIBRARIES = libxcliplist.la
3
4
#AM_CFLAGS = $(DIX_CFLAGS) @SERVER_DEFINES@ @LOADER_DEFINES@
5
AM_CFLAGS = $(DIX_CFLAGS)
6
7
libxcliplist_la_LDFLAGS = -module -avoid-version
8
libxcliplist_ladir = $(moduledir)/extensions
9
10
libxcliplist_la_SOURCES = \
11
	cliplist.c \
12
	cliplistmod.c
13
14
##	cliplistmod.c
15
16
if XORG
17
sdk_HEADERS =
18
endif

Return to bug 389386