Commit 2f79ac44 authored by llyzs's avatar llyzs Committed by llyzs

Redistribute libvncclient as a built-in library. Pleasee see README.LibVNCServer

git-svn-id: https://remmina.svn.sourceforge.net/svnroot/remmina/trunk@14 b6cfa94a-2857-405c-b0d6-536ef9fc39e1
parent c0be0988
## Process this file with automake to produce Makefile.in
SUBDIRS = src po desktop icons
SUBDIRS = libvncserver src po desktop icons
EXTRA_DIST = README.LibVNCServer
LibVNCServer
Project web: http://sourceforge.net/projects/libvncserver
Authors: Johannes Schindelin, Karl J. Runge
License: GPL
Remmina redistributes libvncclient related codes originally from LibVNCServer project. All souce files under libvncserver/* should follow these rules:
o Remmina only maintains Makefile.am. All other files remain untouched
o Remmina can synchronize it with LibVNCServer project any time
o All fixes and new features should be accepted by LibVNCServer project first
Reasons why Remmina redistributes it:
o Remmina only requires small portion of the codes
o Although LibVNCServer is maintained, it does not have any release schedules
# ===========================================================================
# http://autoconf-archive.cryp.to/ax_prefix_config_h.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PREFIX_CONFIG_H [(OUTPUT-HEADER [,PREFIX [,ORIG-HEADER]])]
#
# DESCRIPTION
#
# This is a new variant from ac_prefix_config_ this one will use a
# lowercase-prefix if the config-define was starting with a
# lowercase-char, e.g. "#define const", "#define restrict", or "#define
# off_t", (and this one can live in another directory, e.g.
# testpkg/config.h therefore I decided to move the output-header to be the
# first arg)
#
# takes the usual config.h generated header file; looks for each of the
# generated "#define SOMEDEF" lines, and prefixes the defined name (ie.
# makes it "#define PREFIX_SOMEDEF". The result is written to the output
# config.header file. The PREFIX is converted to uppercase for the
# conversions.
#
# Defaults:
#
# OUTPUT-HEADER = $PACKAGE-config.h
# PREFIX = $PACKAGE
# ORIG-HEADER, from AM_CONFIG_HEADER(config.h)
#
# Your configure.ac script should contain both macros in this order, and
# unlike the earlier variations of this prefix-macro it is okay to place
# the AX_PREFIX_CONFIG_H call before the AC_OUTPUT invokation.
#
# Example:
#
# AC_INIT(config.h.in) # config.h.in as created by "autoheader"
# AM_INIT_AUTOMAKE(testpkg, 0.1.1) # makes #undef VERSION and PACKAGE
# AM_CONFIG_HEADER(config.h) # prep config.h from config.h.in
# AX_PREFIX_CONFIG_H(mylib/_config.h) # prep mylib/_config.h from it..
# AC_MEMORY_H # makes "#undef NEED_MEMORY_H"
# AC_C_CONST_H # makes "#undef const"
# AC_OUTPUT(Makefile) # creates the "config.h" now
# # and also mylib/_config.h
#
# if the argument to AX_PREFIX_CONFIG_H would have been omitted then the
# default outputfile would have been called simply "testpkg-config.h", but
# even under the name "mylib/_config.h" it contains prefix-defines like
#
# #ifndef TESTPKG_VERSION
# #define TESTPKG_VERSION "0.1.1"
# #endif
# #ifndef TESTPKG_NEED_MEMORY_H
# #define TESTPKG_NEED_MEMORY_H 1
# #endif
# #ifndef _testpkg_const
# #define _testpkg_const _const
# #endif
#
# and this "mylib/_config.h" can be installed along with other
# header-files, which is most convenient when creating a shared library
# (that has some headers) where some functionality is dependent on the
# OS-features detected at compile-time. No need to invent some
# "mylib-confdefs.h.in" manually. :-)
#
# Note that some AC_DEFINEs that end up in the config.h file are actually
# self-referential - e.g. AC_C_INLINE, AC_C_CONST, and the AC_TYPE_OFF_T
# say that they "will define inline|const|off_t if the system does not do
# it by itself". You might want to clean up about these - consider an
# extra mylib/conf.h that reads something like:
#
# #include <mylib/_config.h>
# #ifndef _testpkg_const
# #define _testpkg_const const
# #endif
#
# and then start using _testpkg_const in the header files. That is also a
# good thing to differentiate whether some library-user has starting to
# take up with a different compiler, so perhaps it could read something
# like this:
#
# #ifdef _MSC_VER
# #include <mylib/_msvc.h>
# #else
# #include <mylib/_config.h>
# #endif
# #ifndef _testpkg_const
# #define _testpkg_const const
# #endif
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2008 Marten Svantesson
# Copyright (c) 2008 Gerald Point <Gerald.Point@labri.fr>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
AC_DEFUN([AX_PREFIX_CONFIG_H],[dnl
AC_BEFORE([AC_CONFIG_HEADERS],[$0])dnl
AC_CONFIG_COMMANDS([ifelse($1,,$PACKAGE-config.h,$1)],[dnl
AS_VAR_PUSHDEF([_OUT],[ac_prefix_conf_OUT])dnl
AS_VAR_PUSHDEF([_DEF],[ac_prefix_conf_DEF])dnl
AS_VAR_PUSHDEF([_PKG],[ac_prefix_conf_PKG])dnl
AS_VAR_PUSHDEF([_LOW],[ac_prefix_conf_LOW])dnl
AS_VAR_PUSHDEF([_UPP],[ac_prefix_conf_UPP])dnl
AS_VAR_PUSHDEF([_INP],[ac_prefix_conf_INP])dnl
m4_pushdef([_script],[conftest.prefix])dnl
m4_pushdef([_symbol],[m4_cr_Letters[]m4_cr_digits[]_])dnl
_OUT=`echo ifelse($1, , $PACKAGE-config.h, $1)`
_DEF=`echo _$_OUT | sed -e "y:m4_cr_letters:m4_cr_LETTERS[]:" -e "s/@<:@^m4_cr_Letters@:>@/_/g"`
_PKG=`echo ifelse($2, , $PACKAGE, $2)`
_LOW=`echo _$_PKG | sed -e "y:m4_cr_LETTERS-:m4_cr_letters[]_:"`
_UPP=`echo $_PKG | sed -e "y:m4_cr_letters-:m4_cr_LETTERS[]_:" -e "/^@<:@m4_cr_digits@:>@/s/^/_/"`
_INP=`echo "ifelse($3,,,$3)" | sed -e 's/ *//'`
if test ".$_INP" = "."; then
for ac_file in : $CONFIG_HEADERS; do test "_$ac_file" = _: && continue
case "$ac_file" in
*.h) _INP=$ac_file ;;
*)
esac
test ".$_INP" != "." && break
done
fi
if test ".$_INP" = "."; then
case "$_OUT" in
*/*) _INP=`basename "$_OUT"`
;;
*-*) _INP=`echo "$_OUT" | sed -e "s/@<:@_symbol@:>@*-//"`
;;
*) _INP=config.h
;;
esac
fi
if test -z "$_PKG" ; then
AC_MSG_ERROR([no prefix for _PREFIX_PKG_CONFIG_H])
else
if test ! -f "$_INP" ; then if test -f "$srcdir/$_INP" ; then
_INP="$srcdir/$_INP"
fi fi
AC_MSG_NOTICE(creating $_OUT - prefix $_UPP for $_INP defines)
if test -f $_INP ; then
echo "s/^@%:@undef *\\(@<:@m4_cr_LETTERS[]_@:>@\\)/@%:@undef $_UPP""_\\1/" > _script
echo "s/^@%:@undef *\\(@<:@m4_cr_letters@:>@\\)/@%:@undef $_LOW""_\\1/" >> _script
echo "s/^@%:@def[]ine *\\(@<:@m4_cr_LETTERS[]_@:>@@<:@_symbol@:>@*\\)\\(.*\\)/@%:@ifndef $_UPP""_\\1 \\" >> _script
echo "@%:@def[]ine $_UPP""_\\1 \\2 \\" >> _script
echo "@%:@endif/" >>_script
echo "s/^@%:@def[]ine *\\(@<:@m4_cr_letters@:>@@<:@_symbol@:>@*\\)\\(.*\\)/@%:@ifndef $_LOW""_\\1 \\" >> _script
echo "@%:@define $_LOW""_\\1 \\2 \\" >> _script
echo "@%:@endif/" >> _script
# now executing _script on _DEF input to create _OUT output file
echo "@%:@ifndef $_DEF" >$tmp/pconfig.h
echo "@%:@def[]ine $_DEF 1" >>$tmp/pconfig.h
echo ' ' >>$tmp/pconfig.h
echo /'*' $_OUT. Generated automatically at end of configure. '*'/ >>$tmp/pconfig.h
sed -f _script $_INP >>$tmp/pconfig.h
echo ' ' >>$tmp/pconfig.h
echo '/* once:' $_DEF '*/' >>$tmp/pconfig.h
echo "@%:@endif" >>$tmp/pconfig.h
if cmp -s $_OUT $tmp/pconfig.h 2>/dev/null; then
AC_MSG_NOTICE([$_OUT is unchanged])
else
ac_dir=`AS_DIRNAME(["$_OUT"])`
AS_MKDIR_P(["$ac_dir"])
rm -f "$_OUT"
mv $tmp/pconfig.h "$_OUT"
fi
cp _script _configs.sed
else
AC_MSG_ERROR([input file $_INP does not exist - skip generating $_OUT])
fi
rm -f conftest.*
fi
m4_popdef([_symbol])dnl
m4_popdef([_script])dnl
AS_VAR_POPDEF([_INP])dnl
AS_VAR_POPDEF([_UPP])dnl
AS_VAR_POPDEF([_LOW])dnl
AS_VAR_POPDEF([_PKG])dnl
AS_VAR_POPDEF([_DEF])dnl
AS_VAR_POPDEF([_OUT])dnl
],[PACKAGE="$PACKAGE"])])
dnl implementation note: a bug report (31.5.2005) from Marten Svantesson points
dnl out a problem where `echo "\1"` results in a Control-A. The unix standard
dnl http://www.opengroup.org/onlinepubs/000095399/utilities/echo.html
dnl defines all backslash-sequences to be inherently non-portable asking
dnl for replacement mit printf. Some old systems had problems with that
dnl one either. However, the latest libtool (!) release does export an $ECHO
dnl (and $echo) that does the right thing - just one question is left: what
dnl was the first version to have it? Is it greater 2.58 ?
......@@ -15,6 +15,7 @@ fi
aclocal
autoheader --force
libtoolize -c --automake --force
intltoolize -c --automake --force
automake --add-missing --copy --include-deps
autoconf
......
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(remmina, 0.6.99.1)
#AC_PREREQ(2.59)
AC_INIT(config.h.in)
AM_INIT_AUTOMAKE(remmina, 0.6.99.1)
AM_CONFIG_HEADER([config.h])
AC_CONFIG_SRCDIR([src/remmina.c])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE(remmina, 0.6.99.1)
# Checks for programs.
AC_ISC_POSIX
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_LIBTOOL
# Disable optimization if we enable debug
AC_ARG_ENABLE(debug,
......@@ -133,29 +133,42 @@ AC_CHECK_LIB(pthread, pthread_create, [
])
# Check LibVNCClient
AX_PREFIX_CONFIG_H([libvncserver/rfb/rfbconfig.h], [LIBVNCSERVER])
AC_ARG_ENABLE(vnc,
[AS_HELP_STRING([--disable-vnc], [Disable VNC])],
[vnc_support=$enableval],
[vnc_support="yes"]
)
if test "x$vnc_support" != "xno"; then
AC_CHECK_LIB(vncclient, rfbGetClient, [
AC_CHECK_HEADER(rfb/rfbclient.h, [
vnc_support="yes"
LIBS="-lvncclient $LIBS"
AC_DEFINE([HAVE_LIBVNCCLIENT], [1], [Define to 1 if you have the `vncclient' library (-lvncclient).])
AC_CHECK_DECL(LIBVNCSERVER_WITH_CLIENT_TLS, [
vnc_support="yes"
], [
vnc_support="yes (However VeNCrypt/TLS is not supported)"
], [#include "rfb/rfbclient.h"])
], vnc_support="no. libvncclient(libvncserver)-dev required.")
],[
vnc_support="no. libvncclient(libvncserver) required."
])
vnc_support=""
else
vnc_support="disabled."
fi
if test "x$vnc_support" = "x"; then
AC_CHECK_LIB(z, deflate, , vnc_support="no. zlib required.")
fi
if test "x$vnc_support" = "x"; then
AC_CHECK_HEADER(zlib.h, , vnc_support="no. zlib-dev required.")
fi
if test "x$vnc_support" = "x"; then
AC_CHECK_LIB(jpeg, jpeg_CreateCompress, , vnc_support="no. libjpeg required.")
fi
if test "x$vnc_support" = "x"; then
AC_CHECK_HEADER(jpeglib.h, , vnc_support="no. libjpeg-dev required.")
fi
if test "x$vnc_support" = "x"; then
PKG_CHECK_MODULES(GNUTLS, gnutls >= 2.8.0, , vnc_support="no. libgnutls-dev required.")
fi
if test "x$vnc_support" = "x"; then
remmina_pkgs="$remmina_pkgs gnutls"
LIBS="-ljpeg -lz $LIBS"
AC_SUBST(GNUTLS_CFLAGS)
AC_SUBST(GNUTLS_LIBS)
AC_DEFINE([WITH_CLIENT_TLS], [1], [Enable support for gnutls in libvncclient])
AC_DEFINE([HAVE_LIBVNCCLIENT], [1], [Define to 1 if you have libvncclient.])
vnc_support="yes"
fi
# Check libssh
AC_ARG_ENABLE(ssh,
......@@ -225,6 +238,7 @@ src/Makefile
po/Makefile.in
desktop/Makefile
icons/Makefile
libvncserver/Makefile
])
AC_OUTPUT
......
noinst_LTLIBRARIES = libvncclient.la
INCLUDES = $(GNUTLS_CFLAGS)
libvncclient_la_SOURCES = \
libvncclient/cursor.c \
libvncclient/listen.c \
libvncclient/lzoconf.h \
libvncclient/minilzo.c \
libvncclient/minilzo.h \
libvncclient/rfbproto.c \
libvncclient/sockets.c \
libvncclient/tls.c \
libvncclient/tls.h \
libvncclient/tight.c \
libvncclient/vncviewer.c \
libvncclient/zlib.c \
libvncclient/zrle.c
libvncclient_la_LIBADD = $(GNUTLS_LIBS)
EXTRA_DIST = \
libvncclient/corre.c \
libvncclient/hextile.c \
libvncclient/rre.c \
libvncclient/ultra.c \
libvncserver/d3des.c \
libvncserver/d3des.h \
libvncserver/vncauth.c \
libvncserver/zywrletemplate.c
DISTCLEANFILES = \
rfb/rfbconfig.h
noinst_HEADERS = \
rfb/rfbclient.h \
rfb/rfbconfig.h \
rfb/rfbint.h \
rfb/rfbproto.h \
rfb/keysym.h
/*
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
/*
* corre.c - handle CoRRE encoding.
*
* This file shouldn't be compiled directly. It is included multiple times by
* rfbproto.c, each time with a different definition of the macro BPP. For
* each value of BPP, this file defines a function which handles a CoRRE
* encoded rectangle with BPP bits per pixel.
*/
#define HandleCoRREBPP CONCAT2E(HandleCoRRE,BPP)
#define CARDBPP CONCAT3E(uint,BPP,_t)
static rfbBool
HandleCoRREBPP (rfbClient* client, int rx, int ry, int rw, int rh)
{
rfbRREHeader hdr;
int i;
CARDBPP pix;
uint8_t *ptr;
int x, y, w, h;
if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbRREHeader))
return FALSE;
hdr.nSubrects = rfbClientSwap32IfLE(hdr.nSubrects);
if (!ReadFromRFBServer(client, (char *)&pix, sizeof(pix)))
return FALSE;
FillRectangle(client, rx, ry, rw, rh, pix);
if (!ReadFromRFBServer(client, client->buffer, hdr.nSubrects * (4 + (BPP / 8))))
return FALSE;
ptr = (uint8_t *)client->buffer;
for (i = 0; i < hdr.nSubrects; i++) {
pix = *(CARDBPP *)ptr;
ptr += BPP/8;
x = *ptr++;
y = *ptr++;
w = *ptr++;
h = *ptr++;
FillRectangle(client, rx+x, ry+y, w, h, pix);
}
return TRUE;
}
#undef CARDBPP
/*
* Copyright (C) 2001,2002 Constantin Kaplinsky. All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
/*
* cursor.c - code to support cursor shape updates (XCursor and
* RichCursor preudo-encodings).
*/
#include <rfb/rfbclient.h>
#define OPER_SAVE 0
#define OPER_RESTORE 1
#define RGB24_TO_PIXEL(bpp,r,g,b) \
((((uint##bpp##_t)(r) & 0xFF) * client->format.redMax + 127) / 255 \
<< client->format.redShift | \
(((uint##bpp##_t)(g) & 0xFF) * client->format.greenMax + 127) / 255 \
<< client->format.greenShift | \
(((uint##bpp##_t)(b) & 0xFF) * client->format.blueMax + 127) / 255 \
<< client->format.blueShift)
/*********************************************************************
* HandleCursorShape(). Support for XCursor and RichCursor shape
* updates. We emulate cursor operating on the frame buffer (that is
* why we call it "software cursor").
********************************************************************/
rfbBool HandleCursorShape(rfbClient* client,int xhot, int yhot, int width, int height, uint32_t enc)
{
int bytesPerPixel;
size_t bytesPerRow, bytesMaskData;
rfbXCursorColors rgb;
uint32_t colors[2];
char *buf;
uint8_t *ptr;
int x, y, b;
bytesPerPixel = client->format.bitsPerPixel / 8;
bytesPerRow = (width + 7) / 8;
bytesMaskData = bytesPerRow * height;
if (width * height == 0)
return TRUE;
/* Allocate memory for pixel data and temporary mask data. */
if(client->rcSource)
free(client->rcSource);
client->rcSource = malloc(width * height * bytesPerPixel);
if (client->rcSource == NULL)
return FALSE;
buf = malloc(bytesMaskData);
if (buf == NULL) {
free(client->rcSource);
client->rcSource = NULL;
return FALSE;
}
/* Read and decode cursor pixel data, depending on the encoding type. */
if (enc == rfbEncodingXCursor) {
/* Read and convert background and foreground colors. */
if (!ReadFromRFBServer(client, (char *)&rgb, sz_rfbXCursorColors)) {
free(client->rcSource);
client->rcSource = NULL;
free(buf);
return FALSE;
}
colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue);
colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue);
/* Read 1bpp pixel data into a temporary buffer. */
if (!ReadFromRFBServer(client, buf, bytesMaskData)) {
free(client->rcSource);
client->rcSource = NULL;
free(buf);
return FALSE;
}
/* Convert 1bpp data to byte-wide color indices. */
ptr = client->rcSource;
for (y = 0; y < height; y++) {
for (x = 0; x < width / 8; x++) {
for (b = 7; b >= 0; b--) {
*ptr = buf[y * bytesPerRow + x] >> b & 1;
ptr += bytesPerPixel;
}
}
for (b = 7; b > 7 - width % 8; b--) {
*ptr = buf[y * bytesPerRow + x] >> b & 1;
ptr += bytesPerPixel;
}
}
/* Convert indices into the actual pixel values. */
switch (bytesPerPixel) {
case 1:
for (x = 0; x < width * height; x++)
client->rcSource[x] = (uint8_t)colors[client->rcSource[x]];
break;
case 2:
for (x = 0; x < width * height; x++)
((uint16_t *)client->rcSource)[x] = (uint16_t)colors[client->rcSource[x * 2]];
break;
case 4:
for (x = 0; x < width * height; x++)
((uint32_t *)client->rcSource)[x] = colors[client->rcSource[x * 4]];
break;
}
} else { /* enc == rfbEncodingRichCursor */
if (!ReadFromRFBServer(client, (char *)client->rcSource, width * height * bytesPerPixel)) {
free(client->rcSource);
client->rcSource = NULL;
free(buf);
return FALSE;
}
}
/* Read and decode mask data. */
if (!ReadFromRFBServer(client, buf, bytesMaskData)) {
free(client->rcSource);
client->rcSource = NULL;
free(buf);
return FALSE;
}
client->rcMask = malloc(width * height);
if (client->rcMask == NULL) {
free(client->rcSource);
client->rcSource = NULL;
free(buf);
return FALSE;
}
ptr = client->rcMask;
for (y = 0; y < height; y++) {
for (x = 0; x < width / 8; x++) {
for (b = 7; b >= 0; b--) {
*ptr++ = buf[y * bytesPerRow + x] >> b & 1;
}
}
for (b = 7; b > 7 - width % 8; b--) {
*ptr++ = buf[y * bytesPerRow + x] >> b & 1;
}
}
if (client->GotCursorShape != NULL) {
client->GotCursorShape(client, xhot, yhot, width, height, bytesPerPixel);
}
free(buf);
return TRUE;
}
/*
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
/*
* hextile.c - handle hextile encoding.
*
* This file shouldn't be compiled directly. It is included multiple times by
* rfbproto.c, each time with a different definition of the macro BPP. For
* each value of BPP, this file defines a function which handles a hextile
* encoded rectangle with BPP bits per pixel.
*/
#define HandleHextileBPP CONCAT2E(HandleHextile,BPP)
#define CARDBPP CONCAT3E(uint,BPP,_t)
static rfbBool
HandleHextileBPP (rfbClient* client, int rx, int ry, int rw, int rh)
{
CARDBPP bg, fg;
int i;
uint8_t *ptr;
int x, y, w, h;
int sx, sy, sw, sh;
uint8_t subencoding;
uint8_t nSubrects;
for (y = ry; y < ry+rh; y += 16) {
for (x = rx; x < rx+rw; x += 16) {
w = h = 16;
if (rx+rw - x < 16)
w = rx+rw - x;
if (ry+rh - y < 16)
h = ry+rh - y;
if (!ReadFromRFBServer(client, (char *)&subencoding, 1))
return FALSE;
if (subencoding & rfbHextileRaw) {
if (!ReadFromRFBServer(client, client->buffer, w * h * (BPP / 8)))
return FALSE;
CopyRectangle(client, (uint8_t *)client->buffer, x, y, w, h);
continue;
}
if (subencoding & rfbHextileBackgroundSpecified)
if (!ReadFromRFBServer(client, (char *)&bg, sizeof(bg)))
return FALSE;
FillRectangle(client, x, y, w, h, bg);
if (subencoding & rfbHextileForegroundSpecified)
if (!ReadFromRFBServer(client, (char *)&fg, sizeof(fg)))
return FALSE;
if (!(subencoding & rfbHextileAnySubrects)) {
continue;
}
if (!ReadFromRFBServer(client, (char *)&nSubrects, 1))
return FALSE;
ptr = (uint8_t*)client->buffer;
if (subencoding & rfbHextileSubrectsColoured) {
if (!ReadFromRFBServer(client, client->buffer, nSubrects * (2 + (BPP / 8))))
return FALSE;
for (i = 0; i < nSubrects; i++) {
#if BPP==8
GET_PIXEL8(fg, ptr);
#elif BPP==16
GET_PIXEL16(fg, ptr);
#elif BPP==32
GET_PIXEL32(fg, ptr);
#else
#error "Invalid BPP"
#endif
sx = rfbHextileExtractX(*ptr);
sy = rfbHextileExtractY(*ptr);
ptr++;
sw = rfbHextileExtractW(*ptr);
sh = rfbHextileExtractH(*ptr);
ptr++;