diff options
| author | Remko Tronçon <git@el-tramo.be> | 2011-02-01 20:24:32 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2012-04-24 18:16:10 (GMT) | 
| commit | 951cea590db4866188a1e372d6a966df7f0e79f9 (patch) | |
| tree | d71c0bd5ae27c17c2e1ed68793dd1b851d1aa4a4 /3rdParty/LibVNC | |
| parent | 98f0f0c5cee040d3b0df5ff4d695320b2f93da24 (diff) | |
| download | swift-contrib-remko/libvnc.zip swift-contrib-remko/libvnc.tar.bz2  | |
Import part of libvnc.remko/libvnc
Diffstat (limited to '3rdParty/LibVNC')
30 files changed, 16119 insertions, 0 deletions
diff --git a/3rdParty/LibVNC/SConscript b/3rdParty/LibVNC/SConscript new file mode 100644 index 0000000..046acd3 --- /dev/null +++ b/3rdParty/LibVNC/SConscript @@ -0,0 +1,36 @@ +Import(["env", "conf_env"]) + +if env.get("LIBVNC_BUNDLED", False) : + +################################################################################ +# Module flags +################################################################################ + +	if env["SCONS_STAGE"] == "flags" : +		env["LIBVNC_FLAGS"] = { +				"CPPPATH": [Dir("src")], +				"LIBPATH": [Dir(".")], +				"LIBS": ["Swiften_VNC"], +			} + +################################################################################ +# Build +################################################################################ + +	if env["SCONS_STAGE"] == "build" : +		myenv = env.Clone() + +		# Remove warn flags +		myenv.Replace(CCFLAGS = [flag for flag in env["CCFLAGS"] if flag not in ["-W", "-Wall"]]) + +		myenv.Append(CPPPATH = ["src"]) + +		myenv.StaticLibrary("Swiften_VNC", [ +				"src/libvncclient/cursor.c", +				"src/libvncclient/listen.c", +				"src/libvncclient/rfbproto.c", +				"src/libvncclient/sockets.c", +				"src/libvncclient/vncviewer.c", +				"src/libvncclient/minilzo.c", +				"src/libvncclient/tls.c", +			]) diff --git a/3rdParty/LibVNC/src/libvncclient/corre.c b/3rdParty/LibVNC/src/libvncclient/corre.c new file mode 100644 index 0000000..baf91cc --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/corre.c @@ -0,0 +1,70 @@ +/* + *  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 diff --git a/3rdParty/LibVNC/src/libvncclient/cursor.c b/3rdParty/LibVNC/src/libvncclient/cursor.c new file mode 100644 index 0000000..a48d7c5 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/cursor.c @@ -0,0 +1,179 @@ +/* + *  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; +} + + diff --git a/3rdParty/LibVNC/src/libvncclient/hextile.c b/3rdParty/LibVNC/src/libvncclient/hextile.c new file mode 100644 index 0000000..8698445 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/hextile.c @@ -0,0 +1,127 @@ +/* + *  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++; + +	  FillRectangle(client, x+sx, y+sy, sw, sh, fg); +	} + +      } else { +	if (!ReadFromRFBServer(client, client->buffer, nSubrects * 2)) +	  return FALSE; + +	for (i = 0; i < nSubrects; i++) { +	  sx = rfbHextileExtractX(*ptr); +	  sy = rfbHextileExtractY(*ptr); +	  ptr++; +	  sw = rfbHextileExtractW(*ptr); +	  sh = rfbHextileExtractH(*ptr); +	  ptr++; + +	  FillRectangle(client, x+sx, y+sy, sw, sh, fg); +	} +      } +    } +  } + +  return TRUE; +} + +#undef CARDBPP diff --git a/3rdParty/LibVNC/src/libvncclient/listen.c b/3rdParty/LibVNC/src/libvncclient/listen.c new file mode 100644 index 0000000..637abb1 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/listen.c @@ -0,0 +1,171 @@ +/* + *  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. + */ + +/* + * listen.c - listen for incoming connections + */ + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#endif +#include <unistd.h> +#include <sys/types.h> +#ifdef __MINGW32__ +#define close closesocket +#include <winsock2.h> +#else +#include <sys/wait.h> +#include <sys/utsname.h> +#endif +#include <sys/time.h> +#include <rfb/rfbclient.h> + +/* + * listenForIncomingConnections() - listen for incoming connections from + * servers, and fork a new process to deal with each connection. + */ + +void +listenForIncomingConnections(rfbClient* client) +{ +#ifdef __MINGW32__ +  /* FIXME */ +  rfbClientErr("listenForIncomingConnections on MinGW32 NOT IMPLEMENTED\n"); +  return; +#else +  int listenSocket; +  fd_set fds; + +  client->listenSpecified = TRUE; + +  listenSocket = ListenAtTcpPort(client->listenPort); + +  if ((listenSocket < 0)) +    return; + +  rfbClientLog("%s -listen: Listening on port %d\n", +	  client->programName,client->listenPort); +  rfbClientLog("%s -listen: Command line errors are not reported until " +	  "a connection comes in.\n", client->programName); + +  while (TRUE) { + +    /* reap any zombies */ +    int status, pid; +    while ((pid= wait3(&status, WNOHANG, (struct rusage *)0))>0); + +    /* TODO: callback for discard any events (like X11 events) */ + +    FD_ZERO(&fds);  + +    FD_SET(listenSocket, &fds); + +    select(listenSocket+1, &fds, NULL, NULL, NULL); + +    if (FD_ISSET(listenSocket, &fds)) { +      client->sock = AcceptTcpConnection(listenSocket); +      if (client->sock < 0) +	return; +      if (!SetNonBlocking(client->sock)) +	return; + +      /* Now fork off a new process to deal with it... */ + +      switch (fork()) { + +      case -1:  +	rfbClientErr("fork\n");  +	return; + +      case 0: +	/* child - return to caller */ +	close(listenSocket); +	return; + +      default: +	/* parent - go round and listen again */ +	close(client->sock);  +	break; +      } +    } +  } +#endif +} + + + +/* + * listenForIncomingConnectionsNoFork() - listen for incoming connections + * from servers, but DON'T fork, instead just wait timeout microseconds. + * If timeout is negative, block indefinitly. + * Returns 1 on success (there was an incoming connection on the listen socket + * and we accepted it successfully), -1 on error, 0 on timeout. + */ + +int +listenForIncomingConnectionsNoFork(rfbClient* client, int timeout) +{ +  fd_set fds; +  struct timeval to; +  int r; + +  to.tv_sec= timeout / 1000000; +  to.tv_usec= timeout % 1000000; + +  client->listenSpecified = TRUE; + +  if (client->listenSock < 0) +    { +      client->listenSock = ListenAtTcpPort(client->listenPort); + +      if (client->listenSock < 0) +	return -1; + +      rfbClientLog("%s -listennofork: Listening on port %d\n", +		   client->programName,client->listenPort); +      rfbClientLog("%s -listennofork: Command line errors are not reported until " +		   "a connection comes in.\n", client->programName); +    } + +  FD_ZERO(&fds); + +  FD_SET(client->listenSock, &fds); + +  if (timeout < 0) +    r = select(client->listenSock+1, &fds, NULL, NULL, NULL); +  else +    r = select(client->listenSock+1, &fds, NULL, NULL, &to); + +  if (r > 0) +    { +      client->sock = AcceptTcpConnection(client->listenSock); +      if (client->sock < 0) +	return -1; +      if (!SetNonBlocking(client->sock)) +	return -1; + +      close(client->listenSock); +      return r; +    } + +  /* r is now either 0 (timeout) or -1 (error) */ +  return r; +} + + diff --git a/3rdParty/LibVNC/src/libvncclient/lzoconf.h b/3rdParty/LibVNC/src/libvncclient/lzoconf.h new file mode 100644 index 0000000..96db180 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/lzoconf.h @@ -0,0 +1,451 @@ +/* lzoconf.h -- configuration for the LZO real-time data compression library + +   This file is part of the LZO real-time data compression library. + +   Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer +   All Rights Reserved. + +   The LZO library 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. + +   The LZO library 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 the LZO library; see the file COPYING. +   If not, write to the Free Software Foundation, Inc., +   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +   Markus F.X.J. Oberhumer +   <markus@oberhumer.com> +   http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZOCONF_H +#define __LZOCONF_H + +#define LZO_VERSION             0x1080 +#define LZO_VERSION_STRING      "1.08" +#define LZO_VERSION_DATE        "Jul 12 2002" + +/* internal Autoconf configuration file - only used when building LZO */ +#if defined(LZO_HAVE_CONFIG_H) +#  include <config.h> +#endif +#include <limits.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// LZO requires a conforming <limits.h> +************************************************************************/ + +#if !defined(CHAR_BIT) || (CHAR_BIT != 8) +#  error "invalid CHAR_BIT" +#endif +#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +#  error "check your compiler installation" +#endif +#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) +#  error "your limits.h macros are broken" +#endif + +/* workaround a cpp bug under hpux 10.20 */ +#define LZO_0xffffffffL         4294967295ul + +#if !defined(LZO_UINT32_C) +#  if (UINT_MAX < LZO_0xffffffffL) +#    define LZO_UINT32_C(c)     c ## UL +#  else +#    define LZO_UINT32_C(c)     c ## U +#  endif +#endif + + +/*********************************************************************** +// architecture defines +************************************************************************/ + +#if !defined(__LZO_WIN) && !defined(__LZO_DOS) && !defined(__LZO_OS2) +#  if defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +#    define __LZO_WIN +#  elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) +#    define __LZO_WIN +#  elif defined(__NT__) || defined(__NT_DLL__) || defined(__WINDOWS_386__) +#    define __LZO_WIN +#  elif defined(__DOS__) || defined(__MSDOS__) || defined(MSDOS) +#    define __LZO_DOS +#  elif defined(__OS2__) || defined(__OS2V2__) || defined(OS2) +#    define __LZO_OS2 +#  elif defined(__palmos__) +#    define __LZO_PALMOS +#  elif defined(__TOS__) || defined(__atarist__) +#    define __LZO_TOS +#  endif +#endif + +#if (UINT_MAX < LZO_0xffffffffL) +#  if defined(__LZO_WIN) +#    define __LZO_WIN16 +#  elif defined(__LZO_DOS) +#    define __LZO_DOS16 +#  elif defined(__LZO_PALMOS) +#    define __LZO_PALMOS16 +#  elif defined(__LZO_TOS) +#    define __LZO_TOS16 +#  elif defined(__C166__) +#  else +     /* porting hint: for pure 16-bit architectures try compiling +      * everything with -D__LZO_STRICT_16BIT */ +#    error "16-bit target not supported - contact me for porting hints" +#  endif +#endif + +#if !defined(__LZO_i386) +#  if defined(__LZO_DOS) || defined(__LZO_WIN16) +#    define __LZO_i386 +#  elif defined(__i386__) || defined(__386__) || defined(_M_IX86) +#    define __LZO_i386 +#  endif +#endif + +#if defined(__LZO_STRICT_16BIT) +#  if (UINT_MAX < LZO_0xffffffffL) +#    include <lzo16bit.h> +#  endif +#endif + +/* memory checkers */ +#if !defined(__LZO_CHECKER) +#  if defined(__BOUNDS_CHECKING_ON) +#    define __LZO_CHECKER +#  elif defined(__CHECKER__) +#    define __LZO_CHECKER +#  elif defined(__INSURE__) +#    define __LZO_CHECKER +#  elif defined(__PURIFY__) +#    define __LZO_CHECKER +#  endif +#endif + + +/*********************************************************************** +// integral and pointer types +************************************************************************/ + +/* Integral types with 32 bits or more */ +#if !defined(LZO_UINT32_MAX) +#  if (UINT_MAX >= LZO_0xffffffffL) +     typedef unsigned int       lzo_uint32; +     typedef int                lzo_int32; +#    define LZO_UINT32_MAX      UINT_MAX +#    define LZO_INT32_MAX       INT_MAX +#    define LZO_INT32_MIN       INT_MIN +#  elif (ULONG_MAX >= LZO_0xffffffffL) +     typedef unsigned long      lzo_uint32; +     typedef long               lzo_int32; +#    define LZO_UINT32_MAX      ULONG_MAX +#    define LZO_INT32_MAX       LONG_MAX +#    define LZO_INT32_MIN       LONG_MIN +#  else +#    error "lzo_uint32" +#  endif +#endif + +/* lzo_uint is used like size_t */ +#if !defined(LZO_UINT_MAX) +#  if (UINT_MAX >= LZO_0xffffffffL) +     typedef unsigned int       lzo_uint; +     typedef int                lzo_int; +#    define LZO_UINT_MAX        UINT_MAX +#    define LZO_INT_MAX         INT_MAX +#    define LZO_INT_MIN         INT_MIN +#  elif (ULONG_MAX >= LZO_0xffffffffL) +     typedef unsigned long      lzo_uint; +     typedef long               lzo_int; +#    define LZO_UINT_MAX        ULONG_MAX +#    define LZO_INT_MAX         LONG_MAX +#    define LZO_INT_MIN         LONG_MIN +#  else +#    error "lzo_uint" +#  endif +#endif + +typedef int lzo_bool; + + +/*********************************************************************** +// memory models +************************************************************************/ + +/* Memory model for the public code segment. */ +#if !defined(__LZO_CMODEL) +#  if defined(__LZO_DOS16) || defined(__LZO_WIN16) +#    define __LZO_CMODEL        __far +#  elif defined(__LZO_i386) && defined(__WATCOMC__) +#    define __LZO_CMODEL        __near +#  else +#    define __LZO_CMODEL +#  endif +#endif + +/* Memory model for the public data segment. */ +#if !defined(__LZO_DMODEL) +#  if defined(__LZO_DOS16) || defined(__LZO_WIN16) +#    define __LZO_DMODEL        __far +#  elif defined(__LZO_i386) && defined(__WATCOMC__) +#    define __LZO_DMODEL        __near +#  else +#    define __LZO_DMODEL +#  endif +#endif + +/* Memory model that allows to access memory at offsets of lzo_uint. */ +#if !defined(__LZO_MMODEL) +#  if (LZO_UINT_MAX <= UINT_MAX) +#    define __LZO_MMODEL +#  elif defined(__LZO_DOS16) || defined(__LZO_WIN16) +#    define __LZO_MMODEL        __huge +#    define LZO_999_UNSUPPORTED +#  elif defined(__LZO_PALMOS16) || defined(__LZO_TOS16) +#    define __LZO_MMODEL +#  else +#    error "__LZO_MMODEL" +#  endif +#endif + +/* no typedef here because of const-pointer issues */ +#define lzo_byte                unsigned char __LZO_MMODEL +#define lzo_bytep               unsigned char __LZO_MMODEL * +#define lzo_charp               char __LZO_MMODEL * +#define lzo_voidp               void __LZO_MMODEL * +#define lzo_shortp              short __LZO_MMODEL * +#define lzo_ushortp             unsigned short __LZO_MMODEL * +#define lzo_uint32p             lzo_uint32 __LZO_MMODEL * +#define lzo_int32p              lzo_int32 __LZO_MMODEL * +#define lzo_uintp               lzo_uint __LZO_MMODEL * +#define lzo_intp                lzo_int __LZO_MMODEL * +#define lzo_voidpp              lzo_voidp __LZO_MMODEL * +#define lzo_bytepp              lzo_bytep __LZO_MMODEL * + +#ifndef lzo_sizeof_dict_t +#  define lzo_sizeof_dict_t     sizeof(lzo_bytep) +#endif + + +/*********************************************************************** +// calling conventions and function types +************************************************************************/ + +/* linkage */ +#if !defined(__LZO_EXTERN_C) +#  ifdef __cplusplus +#    define __LZO_EXTERN_C      extern "C" +#  else +#    define __LZO_EXTERN_C      extern +#  endif +#endif + +/* calling convention */ +#if !defined(__LZO_CDECL) +#  if defined(__LZO_DOS16) || defined(__LZO_WIN16) +#    define __LZO_CDECL         __LZO_CMODEL __cdecl +#  elif defined(__LZO_i386) && defined(_MSC_VER) +#    define __LZO_CDECL         __LZO_CMODEL __cdecl +#  elif defined(__LZO_i386) && defined(__WATCOMC__) +#    define __LZO_CDECL         __LZO_CMODEL __cdecl +#  else +#    define __LZO_CDECL         __LZO_CMODEL +#  endif +#endif +#if !defined(__LZO_ENTRY) +#  define __LZO_ENTRY           __LZO_CDECL +#endif + +/* C++ exception specification for extern "C" function types */ +#if !defined(__cplusplus) +#  undef LZO_NOTHROW +#  define LZO_NOTHROW +#elif !defined(LZO_NOTHROW) +#  define LZO_NOTHROW +#endif + + +typedef int +(__LZO_ENTRY *lzo_compress_t)   ( const lzo_byte *src, lzo_uint  src_len, +                                        lzo_byte *dst, lzo_uintp dst_len, +                                        lzo_voidp wrkmem ); + +typedef int +(__LZO_ENTRY *lzo_decompress_t) ( const lzo_byte *src, lzo_uint  src_len, +                                        lzo_byte *dst, lzo_uintp dst_len, +                                        lzo_voidp wrkmem ); + +typedef int +(__LZO_ENTRY *lzo_optimize_t)   (       lzo_byte *src, lzo_uint  src_len, +                                        lzo_byte *dst, lzo_uintp dst_len, +                                        lzo_voidp wrkmem ); + +typedef int +(__LZO_ENTRY *lzo_compress_dict_t)(const lzo_byte *src, lzo_uint  src_len, +                                        lzo_byte *dst, lzo_uintp dst_len, +                                        lzo_voidp wrkmem, +                                  const lzo_byte *dict, lzo_uint dict_len ); + +typedef int +(__LZO_ENTRY *lzo_decompress_dict_t)(const lzo_byte *src, lzo_uint  src_len, +                                        lzo_byte *dst, lzo_uintp dst_len, +                                        lzo_voidp wrkmem, +                                  const lzo_byte *dict, lzo_uint dict_len ); + + +/* assembler versions always use __cdecl */ +typedef int +(__LZO_CDECL *lzo_compress_asm_t)( const lzo_byte *src, lzo_uint  src_len, +                                        lzo_byte *dst, lzo_uintp dst_len, +                                        lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_decompress_asm_t)( const lzo_byte *src, lzo_uint  src_len, +                                        lzo_byte *dst, lzo_uintp dst_len, +                                        lzo_voidp wrkmem ); + + +/* a progress indicator callback function */ +typedef void (__LZO_ENTRY *lzo_progress_callback_t) (lzo_uint, lzo_uint); + + +/*********************************************************************** +// export information +************************************************************************/ + +/* DLL export information */ +#if !defined(__LZO_EXPORT1) +#  define __LZO_EXPORT1 +#endif +#if !defined(__LZO_EXPORT2) +#  define __LZO_EXPORT2 +#endif + +/* exported calling convention for C functions */ +#if !defined(LZO_PUBLIC) +#  define LZO_PUBLIC(_rettype) \ +                __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_ENTRY +#endif +#if !defined(LZO_EXTERN) +#  define LZO_EXTERN(_rettype)          __LZO_EXTERN_C LZO_PUBLIC(_rettype) +#endif +#if !defined(LZO_PRIVATE) +#  define LZO_PRIVATE(_rettype)         static _rettype __LZO_ENTRY +#endif + +/* exported __cdecl calling convention for assembler functions */ +#if !defined(LZO_PUBLIC_CDECL) +#  define LZO_PUBLIC_CDECL(_rettype) \ +                __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL +#endif +#if !defined(LZO_EXTERN_CDECL) +#  define LZO_EXTERN_CDECL(_rettype)    __LZO_EXTERN_C LZO_PUBLIC_CDECL(_rettype) +#endif + +/* exported global variables (LZO currently uses no static variables and + * is fully thread safe) */ +#if !defined(LZO_PUBLIC_VAR) +#  define LZO_PUBLIC_VAR(_type) \ +                __LZO_EXPORT1 _type __LZO_EXPORT2 __LZO_DMODEL +#endif +#if !defined(LZO_EXTERN_VAR) +#  define LZO_EXTERN_VAR(_type)         extern LZO_PUBLIC_VAR(_type) +#endif + + +/*********************************************************************** +// error codes and prototypes +************************************************************************/ + +/* Error codes for the compression/decompression functions. Negative + * values are errors, positive values will be used for special but + * normal events. + */ +#define LZO_E_OK                    0 +#define LZO_E_ERROR                 (-1) +#define LZO_E_OUT_OF_MEMORY         (-2)    /* not used right now */ +#define LZO_E_NOT_COMPRESSIBLE      (-3)    /* not used right now */ +#define LZO_E_INPUT_OVERRUN         (-4) +#define LZO_E_OUTPUT_OVERRUN        (-5) +#define LZO_E_LOOKBEHIND_OVERRUN    (-6) +#define LZO_E_EOF_NOT_FOUND         (-7) +#define LZO_E_INPUT_NOT_CONSUMED    (-8) + + +/* lzo_init() should be the first function you call. + * Check the return code ! + * + * lzo_init() is a macro to allow checking that the library and the + * compiler's view of various types are consistent. + */ +#define lzo_init() __lzo_init2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ +    (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\ +    (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ +    (int)sizeof(lzo_compress_t)) +LZO_EXTERN(int) __lzo_init2(unsigned,int,int,int,int,int,int,int,int,int); + +/* version functions (useful for shared libraries) */ +LZO_EXTERN(unsigned) lzo_version(void); +LZO_EXTERN(const char *) lzo_version_string(void); +LZO_EXTERN(const char *) lzo_version_date(void); +LZO_EXTERN(const lzo_charp) _lzo_version_string(void); +LZO_EXTERN(const lzo_charp) _lzo_version_date(void); + +/* string functions */ +LZO_EXTERN(int) +lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memset(lzo_voidp _s, int _c, lzo_uint _len); + +/* checksum functions */ +LZO_EXTERN(lzo_uint32) +lzo_adler32(lzo_uint32 _adler, const lzo_byte *_buf, lzo_uint _len); +LZO_EXTERN(lzo_uint32) +lzo_crc32(lzo_uint32 _c, const lzo_byte *_buf, lzo_uint _len); + +/* misc. */ +LZO_EXTERN(lzo_bool) lzo_assert(int _expr); +LZO_EXTERN(int) _lzo_config_check(void); +typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u; +typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u; +typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t; + +/* align a char pointer on a boundary that is a multiple of `size' */ +LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size); +#define LZO_PTR_ALIGN_UP(_ptr,_size) \ +    ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size))) + +/* deprecated - only for backward compatibility */ +#define LZO_ALIGN(_ptr,_size) LZO_PTR_ALIGN_UP(_ptr,_size) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/3rdParty/LibVNC/src/libvncclient/minilzo.c b/3rdParty/LibVNC/src/libvncclient/minilzo.c new file mode 100644 index 0000000..85771eb --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/minilzo.c @@ -0,0 +1,2935 @@ +/* minilzo.c -- mini subset of the LZO real-time data compression library + +   This file is part of the LZO real-time data compression library. + +   Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer +   All Rights Reserved. + +   The LZO library 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. + +   The LZO library 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 the LZO library; see the file COPYING. +   If not, write to the Free Software Foundation, Inc., +   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +   Markus F.X.J. Oberhumer +   <markus@oberhumer.com> +   http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + *   the full LZO package can be found at + *   http://www.oberhumer.com/opensource/lzo/ + */ + +#define __LZO_IN_MINILZO +#define LZO_BUILD + +#ifdef MINILZO_HAVE_CONFIG_H +#  include <config.h> +#endif + +#undef LZO_HAVE_CONFIG_H +#include "minilzo.h" + +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x1080) +#  error "version mismatch in miniLZO source files" +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +#  define LZO_HAVE_CONFIG_H +#endif + +#if !defined(LZO_NO_SYS_TYPES_H) +#  include <sys/types.h> +#endif +#include <stdio.h> + +#ifndef __LZO_CONF_H +#define __LZO_CONF_H + +#if !defined(__LZO_IN_MINILZO) +#  ifndef __LZOCONF_H +#    include <lzoconf.h> +#  endif +#endif + +#if defined(__BOUNDS_CHECKING_ON) +#  include <unchecked.h> +#else +#  define BOUNDS_CHECKING_OFF_DURING(stmt)      stmt +#  define BOUNDS_CHECKING_OFF_IN_EXPR(expr)     (expr) +#endif + +#if !defined(LZO_HAVE_CONFIG_H) +#  include <stddef.h> +#  include <string.h> +#  if !defined(NO_STDLIB_H) +#    include <stdlib.h> +#  endif +#  define HAVE_MEMCMP +#  define HAVE_MEMCPY +#  define HAVE_MEMMOVE +#  define HAVE_MEMSET +#else +#  include <sys/types.h> +#  if defined(HAVE_STDDEF_H) +#    include <stddef.h> +#  endif +#  if defined(STDC_HEADERS) +#    include <string.h> +#    include <stdlib.h> +#  endif +#endif + +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) +#  define HAVE_MALLOC_H +#  define HAVE_HALLOC +#endif + +#undef NDEBUG +#if !defined(LZO_DEBUG) +#  define NDEBUG +#endif +#if defined(LZO_DEBUG) || !defined(NDEBUG) +#  if !defined(NO_STDIO_H) +#    include <stdio.h> +#  endif +#endif +#include <assert.h> + +#if !defined(LZO_COMPILE_TIME_ASSERT) +#  define LZO_COMPILE_TIME_ASSERT(expr) \ +	{ typedef int __lzo_compile_time_assert_fail[1 - 2 * !(expr)]; } +#endif + +#if !defined(LZO_UNUSED) +#  if 1 +#    define LZO_UNUSED(var)     ((void)&var) +#  elif 0 +#    define LZO_UNUSED(var)     { typedef int __lzo_unused[sizeof(var) ? 2 : 1]; } +#  else +#    define LZO_UNUSED(parm)    (parm = parm) +#  endif +#endif + +#if !defined(__inline__) && !defined(__GNUC__) +#  if defined(__cplusplus) +#    define __inline__      inline +#  else +#    define __inline__ +#  endif +#endif + +#if defined(NO_MEMCMP) +#  undef HAVE_MEMCMP +#endif + +#if !defined(HAVE_MEMCMP) +#  undef memcmp +#  define memcmp    lzo_memcmp +#endif +#if !defined(HAVE_MEMCPY) +#  undef memcpy +#  define memcpy    lzo_memcpy +#endif +#if !defined(HAVE_MEMMOVE) +#  undef memmove +#  define memmove   lzo_memmove +#endif +#if !defined(HAVE_MEMSET) +#  undef memset +#  define memset    lzo_memset +#endif + +#if 0 +#  define LZO_BYTE(x)       ((unsigned char) (x)) +#else +#  define LZO_BYTE(x)       ((unsigned char) ((x) & 0xff)) +#endif + +#define LZO_MAX(a,b)        ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b)        ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c)     ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) +#define LZO_MIN3(a,b,c)     ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) + +#define lzo_sizeof(type)    ((lzo_uint) (sizeof(type))) + +#define LZO_HIGH(array)     ((lzo_uint) (sizeof(array)/sizeof(*(array)))) + +#define LZO_SIZE(bits)      (1u << (bits)) +#define LZO_MASK(bits)      (LZO_SIZE(bits) - 1) + +#define LZO_LSIZE(bits)     (1ul << (bits)) +#define LZO_LMASK(bits)     (LZO_LSIZE(bits) - 1) + +#define LZO_USIZE(bits)     ((lzo_uint) 1 << (bits)) +#define LZO_UMASK(bits)     (LZO_USIZE(bits) - 1) + +#define LZO_STYPE_MAX(b)    (((1l  << (8*(b)-2)) - 1l)  + (1l  << (8*(b)-2))) +#define LZO_UTYPE_MAX(b)    (((1ul << (8*(b)-1)) - 1ul) + (1ul << (8*(b)-1))) + +#if !defined(SIZEOF_UNSIGNED) +#  if (UINT_MAX == 0xffff) +#    define SIZEOF_UNSIGNED         2 +#  elif (UINT_MAX == LZO_0xffffffffL) +#    define SIZEOF_UNSIGNED         4 +#  elif (UINT_MAX >= LZO_0xffffffffL) +#    define SIZEOF_UNSIGNED         8 +#  else +#    error "SIZEOF_UNSIGNED" +#  endif +#endif + +#if !defined(SIZEOF_UNSIGNED_LONG) +#  if (ULONG_MAX == LZO_0xffffffffL) +#    define SIZEOF_UNSIGNED_LONG    4 +#  elif (ULONG_MAX >= LZO_0xffffffffL) +#    define SIZEOF_UNSIGNED_LONG    8 +#  else +#    error "SIZEOF_UNSIGNED_LONG" +#  endif +#endif + +#if !defined(SIZEOF_SIZE_T) +#  define SIZEOF_SIZE_T             SIZEOF_UNSIGNED +#endif +#if !defined(SIZE_T_MAX) +#  define SIZE_T_MAX                LZO_UTYPE_MAX(SIZEOF_SIZE_T) +#endif + +#if 1 && defined(__LZO_i386) && (UINT_MAX == LZO_0xffffffffL) +#  if !defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX == 0xffff) +#    define LZO_UNALIGNED_OK_2 +#  endif +#  if !defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX == LZO_0xffffffffL) +#    define LZO_UNALIGNED_OK_4 +#  endif +#endif + +#if defined(LZO_UNALIGNED_OK_2) || defined(LZO_UNALIGNED_OK_4) +#  if !defined(LZO_UNALIGNED_OK) +#    define LZO_UNALIGNED_OK +#  endif +#endif + +#if defined(__LZO_NO_UNALIGNED) +#  undef LZO_UNALIGNED_OK +#  undef LZO_UNALIGNED_OK_2 +#  undef LZO_UNALIGNED_OK_4 +#endif + +#if defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX != 0xffff) +#  error "LZO_UNALIGNED_OK_2 must not be defined on this system" +#endif +#if defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL) +#  error "LZO_UNALIGNED_OK_4 must not be defined on this system" +#endif + +#if defined(__LZO_NO_ALIGNED) +#  undef LZO_ALIGNED_OK_4 +#endif + +#if defined(LZO_ALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL) +#  error "LZO_ALIGNED_OK_4 must not be defined on this system" +#endif + +#define LZO_LITTLE_ENDIAN       1234 +#define LZO_BIG_ENDIAN          4321 +#define LZO_PDP_ENDIAN          3412 + +#if !defined(LZO_BYTE_ORDER) +#  if defined(MFX_BYTE_ORDER) +#    define LZO_BYTE_ORDER      MFX_BYTE_ORDER +#  elif defined(__LZO_i386) +#    define LZO_BYTE_ORDER      LZO_LITTLE_ENDIAN +#  elif defined(BYTE_ORDER) +#    define LZO_BYTE_ORDER      BYTE_ORDER +#  elif defined(__BYTE_ORDER) +#    define LZO_BYTE_ORDER      __BYTE_ORDER +#  endif +#endif + +#if defined(LZO_BYTE_ORDER) +#  if (LZO_BYTE_ORDER != LZO_LITTLE_ENDIAN) && \ +      (LZO_BYTE_ORDER != LZO_BIG_ENDIAN) +#    error "invalid LZO_BYTE_ORDER" +#  endif +#endif + +#if defined(LZO_UNALIGNED_OK) && !defined(LZO_BYTE_ORDER) +#  error "LZO_BYTE_ORDER is not defined" +#endif + +#define LZO_OPTIMIZE_GNUC_i386_IS_BUGGY + +#if defined(NDEBUG) && !defined(LZO_DEBUG) && !defined(__LZO_CHECKER) +#  if defined(__GNUC__) && defined(__i386__) +#    if !defined(LZO_OPTIMIZE_GNUC_i386_IS_BUGGY) +#      define LZO_OPTIMIZE_GNUC_i386 +#    endif +#  endif +#endif + +__LZO_EXTERN_C int __lzo_init_done; +__LZO_EXTERN_C const lzo_byte __lzo_copyright[]; +LZO_EXTERN(const lzo_byte *) lzo_copyright(void); +__LZO_EXTERN_C const lzo_uint32 _lzo_crc32_table[256]; + +#define _LZO_STRINGIZE(x)           #x +#define _LZO_MEXPAND(x)             _LZO_STRINGIZE(x) + +#define _LZO_CONCAT2(a,b)           a ## b +#define _LZO_CONCAT3(a,b,c)         a ## b ## c +#define _LZO_CONCAT4(a,b,c,d)       a ## b ## c ## d +#define _LZO_CONCAT5(a,b,c,d,e)     a ## b ## c ## d ## e + +#define _LZO_ECONCAT2(a,b)          _LZO_CONCAT2(a,b) +#define _LZO_ECONCAT3(a,b,c)        _LZO_CONCAT3(a,b,c) +#define _LZO_ECONCAT4(a,b,c,d)      _LZO_CONCAT4(a,b,c,d) +#define _LZO_ECONCAT5(a,b,c,d,e)    _LZO_CONCAT5(a,b,c,d,e) + +#if 0 + +#define __LZO_IS_COMPRESS_QUERY(i,il,o,ol,w)    ((lzo_voidp)(o) == (w)) +#define __LZO_QUERY_COMPRESS(i,il,o,ol,w,n,s) \ +		(*ol = (n)*(s), LZO_E_OK) + +#define __LZO_IS_DECOMPRESS_QUERY(i,il,o,ol,w)  ((lzo_voidp)(o) == (w)) +#define __LZO_QUERY_DECOMPRESS(i,il,o,ol,w,n,s) \ +		(*ol = (n)*(s), LZO_E_OK) + +#define __LZO_IS_OPTIMIZE_QUERY(i,il,o,ol,w)    ((lzo_voidp)(o) == (w)) +#define __LZO_QUERY_OPTIMIZE(i,il,o,ol,w,n,s) \ +		(*ol = (n)*(s), LZO_E_OK) + +#endif + +#ifndef __LZO_PTR_H +#define __LZO_PTR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) +#  include <dos.h> +#  if 1 && defined(__WATCOMC__) +#    include <i86.h> +     __LZO_EXTERN_C unsigned char _HShift; +#    define __LZO_HShift    _HShift +#  elif 1 && defined(_MSC_VER) +     __LZO_EXTERN_C unsigned short __near _AHSHIFT; +#    define __LZO_HShift    ((unsigned) &_AHSHIFT) +#  elif defined(__LZO_WIN16) +#    define __LZO_HShift    3 +#  else +#    define __LZO_HShift    12 +#  endif +#  if !defined(_FP_SEG) && defined(FP_SEG) +#    define _FP_SEG         FP_SEG +#  endif +#  if !defined(_FP_OFF) && defined(FP_OFF) +#    define _FP_OFF         FP_OFF +#  endif +#endif + +#if !defined(lzo_ptrdiff_t) +#  if (UINT_MAX >= LZO_0xffffffffL) +     typedef ptrdiff_t          lzo_ptrdiff_t; +#  else +     typedef long               lzo_ptrdiff_t; +#  endif +#endif + +#if !defined(__LZO_HAVE_PTR_T) +#  if defined(lzo_ptr_t) +#    define __LZO_HAVE_PTR_T +#  endif +#endif +#if !defined(__LZO_HAVE_PTR_T) +#  if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_LONG) +#    if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG) +       typedef unsigned long    lzo_ptr_t; +       typedef long             lzo_sptr_t; +#      define __LZO_HAVE_PTR_T +#    endif +#  endif +#endif +#if !defined(__LZO_HAVE_PTR_T) +#  if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED) +#    if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED) +       typedef unsigned int     lzo_ptr_t; +       typedef int              lzo_sptr_t; +#      define __LZO_HAVE_PTR_T +#    endif +#  endif +#endif +#if !defined(__LZO_HAVE_PTR_T) +#  if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_SHORT) +#    if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_SHORT) +       typedef unsigned short   lzo_ptr_t; +       typedef short            lzo_sptr_t; +#      define __LZO_HAVE_PTR_T +#    endif +#  endif +#endif +#if !defined(__LZO_HAVE_PTR_T) +#  if defined(LZO_HAVE_CONFIG_H) || defined(SIZEOF_CHAR_P) +#    error "no suitable type for lzo_ptr_t" +#  else +     typedef unsigned long      lzo_ptr_t; +     typedef long               lzo_sptr_t; +#    define __LZO_HAVE_PTR_T +#  endif +#endif + +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) +#define PTR(a)              ((lzo_bytep) (a)) +#define PTR_ALIGNED_4(a)    ((_FP_OFF(a) & 3) == 0) +#define PTR_ALIGNED2_4(a,b) (((_FP_OFF(a) | _FP_OFF(b)) & 3) == 0) +#else +#define PTR(a)              ((lzo_ptr_t) (a)) +#define PTR_LINEAR(a)       PTR(a) +#define PTR_ALIGNED_4(a)    ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a)    ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b)         (PTR(a) < PTR(b)) +#define PTR_GE(a,b)         (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b)       ((lzo_ptrdiff_t) (PTR(a) - PTR(b))) +#define pd(a,b)             ((lzo_uint) ((a)-(b))) + +LZO_EXTERN(lzo_ptr_t) +__lzo_ptr_linear(const lzo_voidp ptr); + +typedef union +{ +    char            a_char; +    unsigned char   a_uchar; +    short           a_short; +    unsigned short  a_ushort; +    int             a_int; +    unsigned int    a_uint; +    long            a_long; +    unsigned long   a_ulong; +    lzo_int         a_lzo_int; +    lzo_uint        a_lzo_uint; +    lzo_int32       a_lzo_int32; +    lzo_uint32      a_lzo_uint32; +    ptrdiff_t       a_ptrdiff_t; +    lzo_ptrdiff_t   a_lzo_ptrdiff_t; +    lzo_ptr_t       a_lzo_ptr_t; +    lzo_voidp       a_lzo_voidp; +    void *          a_void_p; +    lzo_bytep       a_lzo_bytep; +    lzo_bytepp      a_lzo_bytepp; +    lzo_uintp       a_lzo_uintp; +    lzo_uint *      a_lzo_uint_p; +    lzo_uint32p     a_lzo_uint32p; +    lzo_uint32 *    a_lzo_uint32_p; +    unsigned char * a_uchar_p; +    char *          a_char_p; +} +lzo_full_align_t; + +#ifdef __cplusplus +} +#endif + +#endif + +#define LZO_DETERMINISTIC + +#define LZO_DICT_USE_PTR +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) || defined(__LZO_STRICT_16BIT) +#  undef LZO_DICT_USE_PTR +#endif + +#if defined(LZO_DICT_USE_PTR) +#  define lzo_dict_t    const lzo_bytep +#  define lzo_dict_p    lzo_dict_t __LZO_MMODEL * +#else +#  define lzo_dict_t    lzo_uint +#  define lzo_dict_p    lzo_dict_t __LZO_MMODEL * +#endif + +#if !defined(lzo_moff_t) +#define lzo_moff_t      lzo_uint +#endif + +#endif + +LZO_PUBLIC(lzo_ptr_t) +__lzo_ptr_linear(const lzo_voidp ptr) +{ +    lzo_ptr_t p; + +#if defined(__LZO_DOS16) || defined(__LZO_WIN16) +    p = (((lzo_ptr_t)(_FP_SEG(ptr))) << (16 - __LZO_HShift)) + (_FP_OFF(ptr)); +#else +    p = PTR_LINEAR(ptr); +#endif + +    return p; +} + +LZO_PUBLIC(unsigned) +__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) +{ +    lzo_ptr_t p, s, n; + +    assert(size > 0); + +    p = __lzo_ptr_linear(ptr); +    s = (lzo_ptr_t) (size - 1); +#if 0 +    assert((size & (size - 1)) == 0); +    n = ((p + s) & ~s) - p; +#else +    n = (((p + s) / size) * size) - p; +#endif + +    assert((long)n >= 0); +    assert(n <= s); + +    return (unsigned)n; +} + +#ifndef __LZO_UTIL_H +#define __LZO_UTIL_H + +#ifndef __LZO_CONF_H +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if 1 && defined(HAVE_MEMCPY) +#if !defined(__LZO_DOS16) && !defined(__LZO_WIN16) + +#define MEMCPY8_DS(dest,src,len) \ +    memcpy(dest,src,len); \ +    dest += len; \ +    src += len + +#endif +#endif + +#if 0 && !defined(MEMCPY8_DS) + +#define MEMCPY8_DS(dest,src,len) \ +    { do { \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	len -= 8; \ +    } while (len > 0); } + +#endif + +#if !defined(MEMCPY8_DS) + +#define MEMCPY8_DS(dest,src,len) \ +    { register lzo_uint __l = (len) / 8; \ +    do { \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +	*dest++ = *src++; \ +    } while (--__l > 0); } + +#endif + +#define MEMCPY_DS(dest,src,len) \ +    do *dest++ = *src++; \ +    while (--len > 0) + +#define MEMMOVE_DS(dest,src,len) \ +    do *dest++ = *src++; \ +    while (--len > 0) + +#if 0 && defined(LZO_OPTIMIZE_GNUC_i386) + +#define BZERO8_PTR(s,l,n) \ +__asm__ __volatile__( \ +    "movl  %0,%%eax \n"             \ +    "movl  %1,%%edi \n"             \ +    "movl  %2,%%ecx \n"             \ +    "cld \n"                        \ +    "rep \n"                        \ +    "stosl %%eax,(%%edi) \n"        \ +    :               \ +    :"g" (0),"g" (s),"g" (n)        \ +    :"eax","edi","ecx", "memory", "cc" \ +) + +#elif (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET) + +#if 1 +#define BZERO8_PTR(s,l,n)   memset((s),0,(lzo_uint)(l)*(n)) +#else +#define BZERO8_PTR(s,l,n)   memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) +#endif + +#else + +#define BZERO8_PTR(s,l,n) \ +    lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) + +#endif + +#if 0 +#if defined(__GNUC__) && defined(__i386__) + +unsigned char lzo_rotr8(unsigned char value, int shift); +extern __inline__ unsigned char lzo_rotr8(unsigned char value, int shift) +{ +    unsigned char result; + +    __asm__ __volatile__ ("movb %b1, %b0; rorb %b2, %b0" +			: "=a"(result) : "g"(value), "c"(shift)); +    return result; +} + +unsigned short lzo_rotr16(unsigned short value, int shift); +extern __inline__ unsigned short lzo_rotr16(unsigned short value, int shift) +{ +    unsigned short result; + +    __asm__ __volatile__ ("movw %b1, %b0; rorw %b2, %b0" +			: "=a"(result) : "g"(value), "c"(shift)); +    return result; +} + +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +LZO_PUBLIC(lzo_bool) +lzo_assert(int expr) +{ +    return (expr) ? 1 : 0; +} + +/* If you use the LZO library in a product, you *must* keep this + * copyright string in the executable of your product. + */ + +const lzo_byte __lzo_copyright[] = +#if !defined(__LZO_IN_MINLZO) +    LZO_VERSION_STRING; +#else +    "\n\n\n" +    "LZO real-time data compression library.\n" +    "Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer\n" +    "<markus.oberhumer@jk.uni-linz.ac.at>\n" +    "http://www.oberhumer.com/opensource/lzo/\n" +    "\n" +    "LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE "\n" +    "LZO build date: " __DATE__ " " __TIME__ "\n\n" +    "LZO special compilation options:\n" +#ifdef __cplusplus +    " __cplusplus\n" +#endif +#if defined(__PIC__) +    " __PIC__\n" +#elif defined(__pic__) +    " __pic__\n" +#endif +#if (UINT_MAX < LZO_0xffffffffL) +    " 16BIT\n" +#endif +#if defined(__LZO_STRICT_16BIT) +    " __LZO_STRICT_16BIT\n" +#endif +#if (UINT_MAX > LZO_0xffffffffL) +    " UINT_MAX=" _LZO_MEXPAND(UINT_MAX) "\n" +#endif +#if (ULONG_MAX > LZO_0xffffffffL) +    " ULONG_MAX=" _LZO_MEXPAND(ULONG_MAX) "\n" +#endif +#if defined(LZO_BYTE_ORDER) +    " LZO_BYTE_ORDER=" _LZO_MEXPAND(LZO_BYTE_ORDER) "\n" +#endif +#if defined(LZO_UNALIGNED_OK_2) +    " LZO_UNALIGNED_OK_2\n" +#endif +#if defined(LZO_UNALIGNED_OK_4) +    " LZO_UNALIGNED_OK_4\n" +#endif +#if defined(LZO_ALIGNED_OK_4) +    " LZO_ALIGNED_OK_4\n" +#endif +#if defined(LZO_DICT_USE_PTR) +    " LZO_DICT_USE_PTR\n" +#endif +#if defined(__LZO_QUERY_COMPRESS) +    " __LZO_QUERY_COMPRESS\n" +#endif +#if defined(__LZO_QUERY_DECOMPRESS) +    " __LZO_QUERY_DECOMPRESS\n" +#endif +#if defined(__LZO_IN_MINILZO) +    " __LZO_IN_MINILZO\n" +#endif +    "\n\n" +    "$Id: LZO " LZO_VERSION_STRING " built " __DATE__ " " __TIME__ +#if defined(__GNUC__) && defined(__VERSION__) +    " by gcc " __VERSION__ +#elif defined(__BORLANDC__) +    " by Borland C " _LZO_MEXPAND(__BORLANDC__) +#elif defined(_MSC_VER) +    " by Microsoft C " _LZO_MEXPAND(_MSC_VER) +#elif defined(__PUREC__) +    " by Pure C " _LZO_MEXPAND(__PUREC__) +#elif defined(__SC__) +    " by Symantec C " _LZO_MEXPAND(__SC__) +#elif defined(__TURBOC__) +    " by Turbo C " _LZO_MEXPAND(__TURBOC__) +#elif defined(__WATCOMC__) +    " by Watcom C " _LZO_MEXPAND(__WATCOMC__) +#endif +    " $\n" +    "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer $\n"; +#endif + +LZO_PUBLIC(const lzo_byte *) +lzo_copyright(void) +{ +    return __lzo_copyright; +} + +LZO_PUBLIC(unsigned) +lzo_version(void) +{ +    return LZO_VERSION; +} + +LZO_PUBLIC(const char *) +lzo_version_string(void) +{ +    return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const char *) +lzo_version_date(void) +{ +    return LZO_VERSION_DATE; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_string(void) +{ +    return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_date(void) +{ +    return LZO_VERSION_DATE; +} + +#define LZO_BASE 65521u +#define LZO_NMAX 5552 + +#define LZO_DO1(buf,i)  {s1 += buf[i]; s2 += s1;} +#define LZO_DO2(buf,i)  LZO_DO1(buf,i); LZO_DO1(buf,i+1); +#define LZO_DO4(buf,i)  LZO_DO2(buf,i); LZO_DO2(buf,i+2); +#define LZO_DO8(buf,i)  LZO_DO4(buf,i); LZO_DO4(buf,i+4); +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8); + +LZO_PUBLIC(lzo_uint32) +lzo_adler32(lzo_uint32 adler, const lzo_byte *buf, lzo_uint len) +{ +    lzo_uint32 s1 = adler & 0xffff; +    lzo_uint32 s2 = (adler >> 16) & 0xffff; +    int k; + +    if (buf == NULL) +	return 1; + +    while (len > 0) +    { +	k = len < LZO_NMAX ? (int) len : LZO_NMAX; +	len -= k; +	if (k >= 16) do +	{ +	    LZO_DO16(buf,0); +	    buf += 16; +	    k -= 16; +	} while (k >= 16); +	if (k != 0) do +	{ +	    s1 += *buf++; +	    s2 += s1; +	} while (--k > 0); +	s1 %= LZO_BASE; +	s2 %= LZO_BASE; +    } +    return (s2 << 16) | s1; +} + +LZO_PUBLIC(int) +lzo_memcmp(const lzo_voidp s1, const lzo_voidp s2, lzo_uint len) +{ +#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCMP) +    return memcmp(s1,s2,len); +#else +    const lzo_byte *p1 = (const lzo_byte *) s1; +    const lzo_byte *p2 = (const lzo_byte *) s2; +    int d; + +    if (len > 0) do +    { +	d = *p1 - *p2; +	if (d != 0) +	    return d; +	p1++; +	p2++; +    } +    while (--len > 0); +    return 0; +#endif +} + +LZO_PUBLIC(lzo_voidp) +lzo_memcpy(lzo_voidp dest, const lzo_voidp src, lzo_uint len) +{ +#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCPY) +    return memcpy(dest,src,len); +#else +    lzo_byte *p1 = (lzo_byte *) dest; +    const lzo_byte *p2 = (const lzo_byte *) src; + +    if (len <= 0 || p1 == p2) +	return dest; +    do +	*p1++ = *p2++; +    while (--len > 0); +    return dest; +#endif +} + +LZO_PUBLIC(lzo_voidp) +lzo_memmove(lzo_voidp dest, const lzo_voidp src, lzo_uint len) +{ +#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMMOVE) +    return memmove(dest,src,len); +#else +    lzo_byte *p1 = (lzo_byte *) dest; +    const lzo_byte *p2 = (const lzo_byte *) src; + +    if (len <= 0 || p1 == p2) +	return dest; + +    if (p1 < p2) +    { +	do +	    *p1++ = *p2++; +	while (--len > 0); +    } +    else +    { +	p1 += len; +	p2 += len; +	do +	    *--p1 = *--p2; +	while (--len > 0); +    } +    return dest; +#endif +} + +LZO_PUBLIC(lzo_voidp) +lzo_memset(lzo_voidp s, int c, lzo_uint len) +{ +#if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET) +    return memset(s,c,len); +#else +    lzo_byte *p = (lzo_byte *) s; + +    if (len > 0) do +	*p++ = LZO_BYTE(c); +    while (--len > 0); +    return s; +#endif +} + +#if 0 +#  define IS_SIGNED(type)       (((type) (1ul << (8 * sizeof(type) - 1))) < 0) +#  define IS_UNSIGNED(type)     (((type) (1ul << (8 * sizeof(type) - 1))) > 0) +#else +#  define IS_SIGNED(type)       (((type) (-1)) < ((type) 0)) +#  define IS_UNSIGNED(type)     (((type) (-1)) > ((type) 0)) +#endif + +#define IS_POWER_OF_2(x)        (((x) & ((x) - 1)) == 0) + +static lzo_bool schedule_insns_bug(void); +static lzo_bool strength_reduce_bug(int *); + +#if 0 || defined(LZO_DEBUG) +#include <stdio.h> +static lzo_bool __lzo_assert_fail(const char *s, unsigned line) +{ +#if defined(__palmos__) +    printf("LZO assertion failed in line %u: '%s'\n",line,s); +#else +    fprintf(stderr,"LZO assertion failed in line %u: '%s'\n",line,s); +#endif +    return 0; +} +#  define __lzo_assert(x)   ((x) ? 1 : __lzo_assert_fail(#x,__LINE__)) +#else +#  define __lzo_assert(x)   ((x) ? 1 : 0) +#endif + +#undef COMPILE_TIME_ASSERT +#if 0 +#  define COMPILE_TIME_ASSERT(expr)     r &= __lzo_assert(expr) +#else +#  define COMPILE_TIME_ASSERT(expr)     LZO_COMPILE_TIME_ASSERT(expr) +#endif + +static lzo_bool basic_integral_check(void) +{ +    lzo_bool r = 1; + +    COMPILE_TIME_ASSERT(CHAR_BIT == 8); +    COMPILE_TIME_ASSERT(sizeof(char) == 1); +    COMPILE_TIME_ASSERT(sizeof(short) >= 2); +    COMPILE_TIME_ASSERT(sizeof(long) >= 4); +    COMPILE_TIME_ASSERT(sizeof(int) >= sizeof(short)); +    COMPILE_TIME_ASSERT(sizeof(long) >= sizeof(int)); + +    COMPILE_TIME_ASSERT(sizeof(lzo_uint) == sizeof(lzo_int)); +    COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == sizeof(lzo_int32)); + +    COMPILE_TIME_ASSERT(sizeof(lzo_uint32) >= 4); +    COMPILE_TIME_ASSERT(sizeof(lzo_uint32) >= sizeof(unsigned)); +#if defined(__LZO_STRICT_16BIT) +    COMPILE_TIME_ASSERT(sizeof(lzo_uint) == 2); +#else +    COMPILE_TIME_ASSERT(sizeof(lzo_uint) >= 4); +    COMPILE_TIME_ASSERT(sizeof(lzo_uint) >= sizeof(unsigned)); +#endif + +#if (USHRT_MAX == 65535u) +    COMPILE_TIME_ASSERT(sizeof(short) == 2); +#elif (USHRT_MAX == LZO_0xffffffffL) +    COMPILE_TIME_ASSERT(sizeof(short) == 4); +#elif (USHRT_MAX >= LZO_0xffffffffL) +    COMPILE_TIME_ASSERT(sizeof(short) > 4); +#endif +#if (UINT_MAX == 65535u) +    COMPILE_TIME_ASSERT(sizeof(int) == 2); +#elif (UINT_MAX == LZO_0xffffffffL) +    COMPILE_TIME_ASSERT(sizeof(int) == 4); +#elif (UINT_MAX >= LZO_0xffffffffL) +    COMPILE_TIME_ASSERT(sizeof(int) > 4); +#endif +#if (ULONG_MAX == 65535ul) +    COMPILE_TIME_ASSERT(sizeof(long) == 2); +#elif (ULONG_MAX == LZO_0xffffffffL) +    COMPILE_TIME_ASSERT(sizeof(long) == 4); +#elif (ULONG_MAX >= LZO_0xffffffffL) +    COMPILE_TIME_ASSERT(sizeof(long) > 4); +#endif + +#if defined(SIZEOF_UNSIGNED) +    COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED == sizeof(unsigned)); +#endif +#if defined(SIZEOF_UNSIGNED_LONG) +    COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED_LONG == sizeof(unsigned long)); +#endif +#if defined(SIZEOF_UNSIGNED_SHORT) +    COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED_SHORT == sizeof(unsigned short)); +#endif +#if !defined(__LZO_IN_MINILZO) +#if defined(SIZEOF_SIZE_T) +    COMPILE_TIME_ASSERT(SIZEOF_SIZE_T == sizeof(size_t)); +#endif +#endif + +    COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned char)); +    COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned short)); +    COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned)); +    COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned long)); +    COMPILE_TIME_ASSERT(IS_SIGNED(short)); +    COMPILE_TIME_ASSERT(IS_SIGNED(int)); +    COMPILE_TIME_ASSERT(IS_SIGNED(long)); + +    COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_uint32)); +    COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_uint)); +    COMPILE_TIME_ASSERT(IS_SIGNED(lzo_int32)); +    COMPILE_TIME_ASSERT(IS_SIGNED(lzo_int)); + +    COMPILE_TIME_ASSERT(INT_MAX    == LZO_STYPE_MAX(sizeof(int))); +    COMPILE_TIME_ASSERT(UINT_MAX   == LZO_UTYPE_MAX(sizeof(unsigned))); +    COMPILE_TIME_ASSERT(LONG_MAX   == LZO_STYPE_MAX(sizeof(long))); +    COMPILE_TIME_ASSERT(ULONG_MAX  == LZO_UTYPE_MAX(sizeof(unsigned long))); +    COMPILE_TIME_ASSERT(SHRT_MAX   == LZO_STYPE_MAX(sizeof(short))); +    COMPILE_TIME_ASSERT(USHRT_MAX  == LZO_UTYPE_MAX(sizeof(unsigned short))); +    COMPILE_TIME_ASSERT(LZO_UINT32_MAX == LZO_UTYPE_MAX(sizeof(lzo_uint32))); +    COMPILE_TIME_ASSERT(LZO_UINT_MAX   == LZO_UTYPE_MAX(sizeof(lzo_uint))); +#if !defined(__LZO_IN_MINILZO) +    COMPILE_TIME_ASSERT(SIZE_T_MAX     == LZO_UTYPE_MAX(sizeof(size_t))); +#endif + +    r &= __lzo_assert(LZO_BYTE(257) == 1); + +    return r; +} + +static lzo_bool basic_ptr_check(void) +{ +    lzo_bool r = 1; + +    COMPILE_TIME_ASSERT(sizeof(char *) >= sizeof(int)); +    COMPILE_TIME_ASSERT(sizeof(lzo_byte *) >= sizeof(char *)); + +    COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_byte *)); +    COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_voidpp)); +    COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_bytepp)); +    COMPILE_TIME_ASSERT(sizeof(lzo_voidp) >= sizeof(lzo_uint)); + +    COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) == sizeof(lzo_voidp)); +    COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) == sizeof(lzo_sptr_t)); +    COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) >= sizeof(lzo_uint)); + +    COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= 4); +    COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= sizeof(ptrdiff_t)); + +    COMPILE_TIME_ASSERT(sizeof(ptrdiff_t) >= sizeof(size_t)); +    COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= sizeof(lzo_uint)); + +#if defined(SIZEOF_CHAR_P) +    COMPILE_TIME_ASSERT(SIZEOF_CHAR_P == sizeof(char *)); +#endif +#if defined(SIZEOF_PTRDIFF_T) +    COMPILE_TIME_ASSERT(SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)); +#endif + +    COMPILE_TIME_ASSERT(IS_SIGNED(ptrdiff_t)); +    COMPILE_TIME_ASSERT(IS_UNSIGNED(size_t)); +    COMPILE_TIME_ASSERT(IS_SIGNED(lzo_ptrdiff_t)); +    COMPILE_TIME_ASSERT(IS_SIGNED(lzo_sptr_t)); +    COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_ptr_t)); +    COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_moff_t)); + +    return r; +} + +static lzo_bool ptr_check(void) +{ +    lzo_bool r = 1; +    int i; +    char _wrkmem[10 * sizeof(lzo_byte *) + sizeof(lzo_full_align_t)]; +    lzo_bytep wrkmem; +    lzo_bytepp dict; +    unsigned char x[4 * sizeof(lzo_full_align_t)]; +    long d; +    lzo_full_align_t a; +    lzo_full_align_t u; + +    for (i = 0; i < (int) sizeof(x); i++) +	x[i] = LZO_BYTE(i); + +    wrkmem = LZO_PTR_ALIGN_UP((lzo_byte *)_wrkmem,sizeof(lzo_full_align_t)); + +#if 0 +    dict = (lzo_bytepp) wrkmem; +#else + +    u.a_lzo_bytep = wrkmem; dict = u.a_lzo_bytepp; +#endif + +    d = (long) ((const lzo_bytep) dict - (const lzo_bytep) _wrkmem); +    r &= __lzo_assert(d >= 0); +    r &= __lzo_assert(d < (long) sizeof(lzo_full_align_t)); + +    memset(&a,0,sizeof(a)); +    r &= __lzo_assert(a.a_lzo_voidp == NULL); + +    memset(&a,0xff,sizeof(a)); +    r &= __lzo_assert(a.a_ushort == USHRT_MAX); +    r &= __lzo_assert(a.a_uint == UINT_MAX); +    r &= __lzo_assert(a.a_ulong == ULONG_MAX); +    r &= __lzo_assert(a.a_lzo_uint == LZO_UINT_MAX); +    r &= __lzo_assert(a.a_lzo_uint32 == LZO_UINT32_MAX); + +    if (r == 1) +    { +	for (i = 0; i < 8; i++) +	    r &= __lzo_assert((const lzo_voidp) (&dict[i]) == (const lzo_voidp) (&wrkmem[i * sizeof(lzo_byte *)])); +    } + +    memset(&a,0,sizeof(a)); +    r &= __lzo_assert(a.a_char_p == NULL); +    r &= __lzo_assert(a.a_lzo_bytep == NULL); +    r &= __lzo_assert(NULL == (void *)0); +    if (r == 1) +    { +	for (i = 0; i < 10; i++) +	    dict[i] = wrkmem; +	BZERO8_PTR(dict+1,sizeof(dict[0]),8); +	r &= __lzo_assert(dict[0] == wrkmem); +	for (i = 1; i < 9; i++) +	    r &= __lzo_assert(dict[i] == NULL); +	r &= __lzo_assert(dict[9] == wrkmem); +    } + +    if (r == 1) +    { +	unsigned k = 1; +	const unsigned n = (unsigned) sizeof(lzo_uint32); +	lzo_byte *p0; +	lzo_byte *p1; + +	k += __lzo_align_gap(&x[k],n); +	p0 = (lzo_bytep) &x[k]; +#if defined(PTR_LINEAR) +	r &= __lzo_assert((PTR_LINEAR(p0) & (n-1)) == 0); +#else +	r &= __lzo_assert(n == 4); +	r &= __lzo_assert(PTR_ALIGNED_4(p0)); +#endif + +	r &= __lzo_assert(k >= 1); +	p1 = (lzo_bytep) &x[1]; +	r &= __lzo_assert(PTR_GE(p0,p1)); + +	r &= __lzo_assert(k < 1+n); +	p1 = (lzo_bytep) &x[1+n]; +	r &= __lzo_assert(PTR_LT(p0,p1)); + +	if (r == 1) +	{ +	    lzo_uint32 v0, v1; +#if 0 +	    v0 = * (lzo_uint32 *) &x[k]; +	    v1 = * (lzo_uint32 *) &x[k+n]; +#else + +	    u.a_uchar_p = &x[k]; +	    v0 = *u.a_lzo_uint32_p; +	    u.a_uchar_p = &x[k+n]; +	    v1 = *u.a_lzo_uint32_p; +#endif +	    r &= __lzo_assert(v0 > 0); +	    r &= __lzo_assert(v1 > 0); +	} +    } + +    return r; +} + +LZO_PUBLIC(int) +_lzo_config_check(void) +{ +    lzo_bool r = 1; +    int i; +    union { +	lzo_uint32 a; +	unsigned short b; +	lzo_uint32 aa[4]; +	unsigned char x[4*sizeof(lzo_full_align_t)]; +    } u; + +    COMPILE_TIME_ASSERT( (int) ((unsigned char) ((signed char) -1)) == 255); +    COMPILE_TIME_ASSERT( (((unsigned char)128) << (int)(8*sizeof(int)-8)) < 0); + +#if 0 +    r &= __lzo_assert((const void *)&u == (const void *)&u.a); +    r &= __lzo_assert((const void *)&u == (const void *)&u.b); +    r &= __lzo_assert((const void *)&u == (const void *)&u.x[0]); +    r &= __lzo_assert((const void *)&u == (const void *)&u.aa[0]); +#endif + +    r &= basic_integral_check(); +    r &= basic_ptr_check(); +    if (r != 1) +	return LZO_E_ERROR; + +    u.a = 0; u.b = 0; +    for (i = 0; i < (int) sizeof(u.x); i++) +	u.x[i] = LZO_BYTE(i); + +#if defined(LZO_BYTE_ORDER) +    if (r == 1) +    { +#  if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) +	lzo_uint32 a = (lzo_uint32) (u.a & LZO_0xffffffffL); +	unsigned short b = (unsigned short) (u.b & 0xffff); +	r &= __lzo_assert(a == 0x03020100L); +	r &= __lzo_assert(b == 0x0100); +#  elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN) +	lzo_uint32 a = u.a >> (8 * sizeof(u.a) - 32); +	unsigned short b = u.b >> (8 * sizeof(u.b) - 16); +	r &= __lzo_assert(a == 0x00010203L); +	r &= __lzo_assert(b == 0x0001); +#  else +#    error "invalid LZO_BYTE_ORDER" +#  endif +    } +#endif + +#if defined(LZO_UNALIGNED_OK_2) +    COMPILE_TIME_ASSERT(sizeof(short) == 2); +    if (r == 1) +    { +	unsigned short b[4]; + +	for (i = 0; i < 4; i++) +	    b[i] = * (const unsigned short *) &u.x[i]; + +#  if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) +	r &= __lzo_assert(b[0] == 0x0100); +	r &= __lzo_assert(b[1] == 0x0201); +	r &= __lzo_assert(b[2] == 0x0302); +	r &= __lzo_assert(b[3] == 0x0403); +#  elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN) +	r &= __lzo_assert(b[0] == 0x0001); +	r &= __lzo_assert(b[1] == 0x0102); +	r &= __lzo_assert(b[2] == 0x0203); +	r &= __lzo_assert(b[3] == 0x0304); +#  endif +    } +#endif + +#if defined(LZO_UNALIGNED_OK_4) +    COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == 4); +    if (r == 1) +    { +	lzo_uint32 a[4]; + +	for (i = 0; i < 4; i++) +	    a[i] = * (const lzo_uint32 *) &u.x[i]; + +#  if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) +	r &= __lzo_assert(a[0] == 0x03020100L); +	r &= __lzo_assert(a[1] == 0x04030201L); +	r &= __lzo_assert(a[2] == 0x05040302L); +	r &= __lzo_assert(a[3] == 0x06050403L); +#  elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN) +	r &= __lzo_assert(a[0] == 0x00010203L); +	r &= __lzo_assert(a[1] == 0x01020304L); +	r &= __lzo_assert(a[2] == 0x02030405L); +	r &= __lzo_assert(a[3] == 0x03040506L); +#  endif +    } +#endif + +#if defined(LZO_ALIGNED_OK_4) +    COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == 4); +#endif + +    COMPILE_TIME_ASSERT(lzo_sizeof_dict_t == sizeof(lzo_dict_t)); + +#if defined(__LZO_IN_MINLZO) +    if (r == 1) +    { +	lzo_uint32 adler; +	adler = lzo_adler32(0, NULL, 0); +	adler = lzo_adler32(adler, lzo_copyright(), 200); +	r &= __lzo_assert(adler == 0xc76f1751L); +    } +#endif + +    if (r == 1) +    { +	r &= __lzo_assert(!schedule_insns_bug()); +    } + +    if (r == 1) +    { +	static int x[3]; +	static unsigned xn = 3; +	register unsigned j; + +	for (j = 0; j < xn; j++) +	    x[j] = (int)j - 3; +	r &= __lzo_assert(!strength_reduce_bug(x)); +    } + +    if (r == 1) +    { +	r &= ptr_check(); +    } + +    return r == 1 ? LZO_E_OK : LZO_E_ERROR; +} + +static lzo_bool schedule_insns_bug(void) +{ +#if defined(__LZO_CHECKER) +    return 0; +#else +    const int clone[] = {1, 2, 0}; +    const int *q; +    q = clone; +    return (*q) ? 0 : 1; +#endif +} + +static lzo_bool strength_reduce_bug(int *x) +{ +    return x[0] != -3 || x[1] != -2 || x[2] != -1; +} + +#undef COMPILE_TIME_ASSERT + +int __lzo_init_done = 0; + +LZO_PUBLIC(int) +__lzo_init2(unsigned v, int s1, int s2, int s3, int s4, int s5, +			int s6, int s7, int s8, int s9) +{ +    int r; + +    __lzo_init_done = 1; + +    if (v == 0) +	return LZO_E_ERROR; + +    r = (s1 == -1 || s1 == (int) sizeof(short)) && +	(s2 == -1 || s2 == (int) sizeof(int)) && +	(s3 == -1 || s3 == (int) sizeof(long)) && +	(s4 == -1 || s4 == (int) sizeof(lzo_uint32)) && +	(s5 == -1 || s5 == (int) sizeof(lzo_uint)) && +	(s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && +	(s7 == -1 || s7 == (int) sizeof(char *)) && +	(s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && +	(s9 == -1 || s9 == (int) sizeof(lzo_compress_t)); +    if (!r) +	return LZO_E_ERROR; + +    r = _lzo_config_check(); +    if (r != LZO_E_OK) +	return r; + +    return r; +} + +#if !defined(__LZO_IN_MINILZO) + +LZO_EXTERN(int) +__lzo_init(unsigned v,int s1,int s2,int s3,int s4,int s5,int s6,int s7); + +LZO_PUBLIC(int) +__lzo_init(unsigned v,int s1,int s2,int s3,int s4,int s5,int s6,int s7) +{ +    if (v == 0 || v > 0x1010) +	return LZO_E_ERROR; +    return __lzo_init2(v,s1,s2,s3,s4,s5,-1,-1,s6,s7); +} + +#endif + +#define do_compress         _lzo1x_1_do_compress + +#define LZO_NEED_DICT_H +#define D_BITS          14 +#define D_INDEX1(d,p)       d = DM((0x21*DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p)       d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) + +#ifndef __LZO_CONFIG1X_H +#define __LZO_CONFIG1X_H + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +#  define LZO1X +#endif + +#if !defined(__LZO_IN_MINILZO) +#include <lzo1x.h> +#endif + +#define LZO_EOF_CODE +#undef LZO_DETERMINISTIC + +#define M1_MAX_OFFSET   0x0400 +#ifndef M2_MAX_OFFSET +#define M2_MAX_OFFSET   0x0800 +#endif +#define M3_MAX_OFFSET   0x4000 +#define M4_MAX_OFFSET   0xbfff + +#define MX_MAX_OFFSET   (M1_MAX_OFFSET + M2_MAX_OFFSET) + +#define M1_MIN_LEN      2 +#define M1_MAX_LEN      2 +#define M2_MIN_LEN      3 +#ifndef M2_MAX_LEN +#define M2_MAX_LEN      8 +#endif +#define M3_MIN_LEN      3 +#define M3_MAX_LEN      33 +#define M4_MIN_LEN      3 +#define M4_MAX_LEN      9 + +#define M1_MARKER       0 +#define M2_MARKER       64 +#define M3_MARKER       32 +#define M4_MARKER       16 + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD       (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH            LZO_HASH_LZO_INCREMENTAL_B +#endif +#define DL_MIN_LEN          M2_MIN_LEN + +#ifndef __LZO_DICT_H +#define __LZO_DICT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(D_BITS) && defined(DBITS) +#  define D_BITS        DBITS +#endif +#if !defined(D_BITS) +#  error "D_BITS is not defined" +#endif +#if (D_BITS < 16) +#  define D_SIZE        LZO_SIZE(D_BITS) +#  define D_MASK        LZO_MASK(D_BITS) +#else +#  define D_SIZE        LZO_USIZE(D_BITS) +#  define D_MASK        LZO_UMASK(D_BITS) +#endif +#define D_HIGH          ((D_MASK >> 1) + 1) + +#if !defined(DD_BITS) +#  define DD_BITS       0 +#endif +#define DD_SIZE         LZO_SIZE(DD_BITS) +#define DD_MASK         LZO_MASK(DD_BITS) + +#if !defined(DL_BITS) +#  define DL_BITS       (D_BITS - DD_BITS) +#endif +#if (DL_BITS < 16) +#  define DL_SIZE       LZO_SIZE(DL_BITS) +#  define DL_MASK       LZO_MASK(DL_BITS) +#else +#  define DL_SIZE       LZO_USIZE(DL_BITS) +#  define DL_MASK       LZO_UMASK(DL_BITS) +#endif + +#if (D_BITS != DL_BITS + DD_BITS) +#  error "D_BITS does not match" +#endif +#if (D_BITS < 8 || D_BITS > 18) +#  error "invalid D_BITS" +#endif +#if (DL_BITS < 8 || DL_BITS > 20) +#  error "invalid DL_BITS" +#endif +#if (DD_BITS < 0 || DD_BITS > 6) +#  error "invalid DD_BITS" +#endif + +#if !defined(DL_MIN_LEN) +#  define DL_MIN_LEN    3 +#endif +#if !defined(DL_SHIFT) +#  define DL_SHIFT      ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) +#endif + +#define LZO_HASH_GZIP                   1 +#define LZO_HASH_GZIP_INCREMENTAL       2 +#define LZO_HASH_LZO_INCREMENTAL_A      3 +#define LZO_HASH_LZO_INCREMENTAL_B      4 + +#if !defined(LZO_HASH) +#  error "choose a hashing strategy" +#endif + +#if (DL_MIN_LEN == 3) +#  define _DV2_A(p,shift1,shift2) \ +	(((( (lzo_uint32)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) +#  define _DV2_B(p,shift1,shift2) \ +	(((( (lzo_uint32)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) +#  define _DV3_B(p,shift1,shift2,shift3) \ +	((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) +#elif (DL_MIN_LEN == 2) +#  define _DV2_A(p,shift1,shift2) \ +	(( (lzo_uint32)(p[0]) << shift1) ^ p[1]) +#  define _DV2_B(p,shift1,shift2) \ +	(( (lzo_uint32)(p[1]) << shift1) ^ p[2]) +#else +#  error "invalid DL_MIN_LEN" +#endif +#define _DV_A(p,shift)      _DV2_A(p,shift,shift) +#define _DV_B(p,shift)      _DV2_B(p,shift,shift) +#define DA2(p,s1,s2) \ +	(((((lzo_uint32)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) +#define DS2(p,s1,s2) \ +	(((((lzo_uint32)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) +#define DX2(p,s1,s2) \ +	(((((lzo_uint32)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) +#define DMS(v,s)        ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v)           DMS(v,0) + +#if (LZO_HASH == LZO_HASH_GZIP) +#  define _DINDEX(dv,p)     (_DV_A((p),DL_SHIFT)) + +#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) +#  define __LZO_HASH_INCREMENTAL +#  define DVAL_FIRST(dv,p)  dv = _DV_A((p),DL_SHIFT) +#  define DVAL_NEXT(dv,p)   dv = (((dv) << DL_SHIFT) ^ p[2]) +#  define _DINDEX(dv,p)     (dv) +#  define DVAL_LOOKAHEAD    DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) +#  define __LZO_HASH_INCREMENTAL +#  define DVAL_FIRST(dv,p)  dv = _DV_A((p),5) +#  define DVAL_NEXT(dv,p) \ +		dv ^= (lzo_uint32)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) +#  define _DINDEX(dv,p)     ((0x9f5f * (dv)) >> 5) +#  define DVAL_LOOKAHEAD    DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) +#  define __LZO_HASH_INCREMENTAL +#  define DVAL_FIRST(dv,p)  dv = _DV_B((p),5) +#  define DVAL_NEXT(dv,p) \ +		dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_uint32)(p[2]) << (2*5))) +#  define _DINDEX(dv,p)     ((0x9f5f * (dv)) >> 5) +#  define DVAL_LOOKAHEAD    DL_MIN_LEN + +#else +#  error "choose a hashing strategy" +#endif + +#ifndef DINDEX +#define DINDEX(dv,p)        ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) +#endif +#if !defined(DINDEX1) && defined(D_INDEX1) +#define DINDEX1             D_INDEX1 +#endif +#if !defined(DINDEX2) && defined(D_INDEX2) +#define DINDEX2             D_INDEX2 +#endif + +#if !defined(__LZO_HASH_INCREMENTAL) +#  define DVAL_FIRST(dv,p)  ((void) 0) +#  define DVAL_NEXT(dv,p)   ((void) 0) +#  define DVAL_LOOKAHEAD    0 +#endif + +#if !defined(DVAL_ASSERT) +#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) +static void DVAL_ASSERT(lzo_uint32 dv, const lzo_byte *p) +{ +    lzo_uint32 df; +    DVAL_FIRST(df,(p)); +    assert(DINDEX(dv,p) == DINDEX(df,p)); +} +#else +#  define DVAL_ASSERT(dv,p) ((void) 0) +#endif +#endif + +#if defined(LZO_DICT_USE_PTR) +#  define DENTRY(p,in)                          (p) +#  define GINDEX(m_pos,m_off,dict,dindex,in)    m_pos = dict[dindex] +#else +#  define DENTRY(p,in)                          ((lzo_uint) ((p)-(in))) +#  define GINDEX(m_pos,m_off,dict,dindex,in)    m_off = dict[dindex] +#endif + +#if (DD_BITS == 0) + +#  define UPDATE_D(dict,drun,dv,p,in)       dict[ DINDEX(dv,p) ] = DENTRY(p,in) +#  define UPDATE_I(dict,drun,index,p,in)    dict[index] = DENTRY(p,in) +#  define UPDATE_P(ptr,drun,p,in)           (ptr)[0] = DENTRY(p,in) + +#else + +#  define UPDATE_D(dict,drun,dv,p,in)   \ +	dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +#  define UPDATE_I(dict,drun,index,p,in)    \ +	dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +#  define UPDATE_P(ptr,drun,p,in)   \ +	(ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK + +#endif + +#if defined(LZO_DICT_USE_PTR) + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ +	(m_pos == NULL || (m_off = (lzo_moff_t) (ip - m_pos)) > max_offset) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ +    (BOUNDS_CHECKING_OFF_IN_EXPR( \ +	(PTR_LT(m_pos,in) || \ +	 (m_off = (lzo_moff_t) PTR_DIFF(ip,m_pos)) <= 0 || \ +	  m_off > max_offset) )) + +#else + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ +	(m_off == 0 || \ +	 ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \ +	 (m_pos = (ip) - (m_off), 0) ) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ +	((lzo_moff_t) ((ip)-(in)) <= m_off || \ +	 ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \ +	 (m_pos = (ip) - (m_off), 0) ) + +#endif + +#if defined(LZO_DETERMINISTIC) +#  define LZO_CHECK_MPOS    LZO_CHECK_MPOS_DET +#else +#  define LZO_CHECK_MPOS    LZO_CHECK_MPOS_NON_DET +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +#endif + +#define DO_COMPRESS     lzo1x_1_compress + +static +lzo_uint do_compress     ( const lzo_byte *in , lzo_uint  in_len, +				 lzo_byte *out, lzo_uintp out_len, +				 lzo_voidp wrkmem ) +{ +#if 0 && defined(__GNUC__) && defined(__i386__) +    register const lzo_byte *ip __asm__("%esi"); +#else +    register const lzo_byte *ip; +#endif +    lzo_byte *op; +    const lzo_byte * const in_end = in + in_len; +    const lzo_byte * const ip_end = in + in_len - M2_MAX_LEN - 5; +    const lzo_byte *ii; +    lzo_dict_p const dict = (lzo_dict_p) wrkmem; + +    op = out; +    ip = in; +    ii = ip; + +    ip += 4; +    for (;;) +    { +#if 0 && defined(__GNUC__) && defined(__i386__) +	register const lzo_byte *m_pos __asm__("%edi"); +#else +	register const lzo_byte *m_pos; +#endif +	lzo_moff_t m_off; +	lzo_uint m_len; +	lzo_uint dindex; + +	DINDEX1(dindex,ip); +	GINDEX(m_pos,m_off,dict,dindex,in); +	if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) +	    goto literal; +#if 1 +	if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) +	    goto try_match; +	DINDEX2(dindex,ip); +#endif +	GINDEX(m_pos,m_off,dict,dindex,in); +	if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) +	    goto literal; +	if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) +	    goto try_match; +	goto literal; + +try_match: +#if 1 && defined(LZO_UNALIGNED_OK_2) +	if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip) +#else +	if (m_pos[0] != ip[0] || m_pos[1] != ip[1]) +#endif +	{ +	} +	else +	{ +	    if (m_pos[2] == ip[2]) +	    { +#if 0 +		if (m_off <= M2_MAX_OFFSET) +		    goto match; +		if (lit <= 3) +		    goto match; +		if (lit == 3) +		{ +		    assert(op - 2 > out); op[-2] |= LZO_BYTE(3); +		    *op++ = *ii++; *op++ = *ii++; *op++ = *ii++; +		    goto code_match; +		} +		if (m_pos[3] == ip[3]) +#endif +		    goto match; +	    } +	    else +	    { +#if 0 +#if 0 +		if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3) +#else +		if (m_off <= M1_MAX_OFFSET && lit == 3) +#endif +		{ +		    register lzo_uint t; + +		    t = lit; +		    assert(op - 2 > out); op[-2] |= LZO_BYTE(t); +		    do *op++ = *ii++; while (--t > 0); +		    assert(ii == ip); +		    m_off -= 1; +		    *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2)); +		    *op++ = LZO_BYTE(m_off >> 2); +		    ip += 2; +		    goto match_done; +		} +#endif +	    } +	} + +literal: +	UPDATE_I(dict,0,dindex,ip,in); +	++ip; +	if (ip >= ip_end) +	    break; +	continue; + +match: +	UPDATE_I(dict,0,dindex,ip,in); +	if (pd(ip,ii) > 0) +	{ +	    register lzo_uint t = pd(ip,ii); + +	    if (t <= 3) +	    { +		assert(op - 2 > out); +		op[-2] |= LZO_BYTE(t); +	    } +	    else if (t <= 18) +		*op++ = LZO_BYTE(t - 3); +	    else +	    { +		register lzo_uint tt = t - 18; + +		*op++ = 0; +		while (tt > 255) +		{ +		    tt -= 255; +		    *op++ = 0; +		} +		assert(tt > 0); +		*op++ = LZO_BYTE(tt); +	    } +	    do *op++ = *ii++; while (--t > 0); +	} + +	assert(ii == ip); +	ip += 3; +	if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ || +	    m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++ +#ifdef LZO1Y +	    || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++ +	    || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++ +#endif +	   ) +	{ +	    --ip; +	    m_len = ip - ii; +	    assert(m_len >= 3); assert(m_len <= M2_MAX_LEN); + +	    if (m_off <= M2_MAX_OFFSET) +	    { +		m_off -= 1; +#if defined(LZO1X) +		*op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); +		*op++ = LZO_BYTE(m_off >> 3); +#elif defined(LZO1Y) +		*op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); +		*op++ = LZO_BYTE(m_off >> 2); +#endif +	    } +	    else if (m_off <= M3_MAX_OFFSET) +	    { +		m_off -= 1; +		*op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); +		goto m3_m4_offset; +	    } +	    else +#if defined(LZO1X) +	    { +		m_off -= 0x4000; +		assert(m_off > 0); assert(m_off <= 0x7fff); +		*op++ = LZO_BYTE(M4_MARKER | +				 ((m_off & 0x4000) >> 11) | (m_len - 2)); +		goto m3_m4_offset; +	    } +#elif defined(LZO1Y) +		goto m4_match; +#endif +	} +	else +	{ +	    { +		const lzo_byte *end = in_end; +		const lzo_byte *m = m_pos + M2_MAX_LEN + 1; +		while (ip < end && *m == *ip) +		    m++, ip++; +		m_len = (ip - ii); +	    } +	    assert(m_len > M2_MAX_LEN); + +	    if (m_off <= M3_MAX_OFFSET) +	    { +		m_off -= 1; +		if (m_len <= 33) +		    *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); +		else +		{ +		    m_len -= 33; +		    *op++ = M3_MARKER | 0; +		    goto m3_m4_len; +		} +	    } +	    else +	    { +#if defined(LZO1Y) +m4_match: +#endif +		m_off -= 0x4000; +		assert(m_off > 0); assert(m_off <= 0x7fff); +		if (m_len <= M4_MAX_LEN) +		    *op++ = LZO_BYTE(M4_MARKER | +				     ((m_off & 0x4000) >> 11) | (m_len - 2)); +		else +		{ +		    m_len -= M4_MAX_LEN; +		    *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11)); +m3_m4_len: +		    while (m_len > 255) +		    { +			m_len -= 255; +			*op++ = 0; +		    } +		    assert(m_len > 0); +		    *op++ = LZO_BYTE(m_len); +		} +	    } + +m3_m4_offset: +	    *op++ = LZO_BYTE((m_off & 63) << 2); +	    *op++ = LZO_BYTE(m_off >> 6); +	} + +#if 0 +match_done: +#endif +	ii = ip; +	if (ip >= ip_end) +	    break; +    } + +    *out_len = op - out; +    return pd(in_end,ii); +} + +LZO_PUBLIC(int) +DO_COMPRESS      ( const lzo_byte *in , lzo_uint  in_len, +			 lzo_byte *out, lzo_uintp out_len, +			 lzo_voidp wrkmem ) +{ +    lzo_byte *op = out; +    lzo_uint t; + +#if defined(__LZO_QUERY_COMPRESS) +    if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) +	return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t)); +#endif + +    if (in_len <= M2_MAX_LEN + 5) +	t = in_len; +    else +    { +	t = do_compress(in,in_len,op,out_len,wrkmem); +	op += *out_len; +    } + +    if (t > 0) +    { +	const lzo_byte *ii = in + in_len - t; + +	if (op == out && t <= 238) +	    *op++ = LZO_BYTE(17 + t); +	else if (t <= 3) +	    op[-2] |= LZO_BYTE(t); +	else if (t <= 18) +	    *op++ = LZO_BYTE(t - 3); +	else +	{ +	    lzo_uint tt = t - 18; + +	    *op++ = 0; +	    while (tt > 255) +	    { +		tt -= 255; +		*op++ = 0; +	    } +	    assert(tt > 0); +	    *op++ = LZO_BYTE(tt); +	} +	do *op++ = *ii++; while (--t > 0); +    } + +    *op++ = M4_MARKER | 1; +    *op++ = 0; +    *op++ = 0; + +    *out_len = op - out; +    return LZO_E_OK; +} + +#undef do_compress +#undef DO_COMPRESS +#undef LZO_HASH + +#undef LZO_TEST_DECOMPRESS_OVERRUN +#undef LZO_TEST_DECOMPRESS_OVERRUN_INPUT +#undef LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT +#undef LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND +#undef DO_DECOMPRESS +#define DO_DECOMPRESS       lzo1x_decompress + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN) +#  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT) +#    define LZO_TEST_DECOMPRESS_OVERRUN_INPUT       2 +#  endif +#  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT) +#    define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT      2 +#  endif +#  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +#    define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND +#  endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LOOKBEHIND +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT) +#  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1) +#    define TEST_IP             (ip < ip_end) +#  endif +#  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2) +#    define NEED_IP(x) \ +	    if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x))  goto input_overrun +#  endif +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT) +#  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1) +#    define TEST_OP             (op <= op_end) +#  endif +#  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2) +#    undef TEST_OP +#    define NEED_OP(x) \ +	    if ((lzo_uint)(op_end - op) < (lzo_uint)(x))  goto output_overrun +#  endif +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +#  define TEST_LOOKBEHIND(m_pos,out)    if (m_pos < out) goto lookbehind_overrun +#else +#  define TEST_LOOKBEHIND(m_pos,op)     ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +#  define TEST_IP               (ip < ip_end) +#endif + +#if defined(TEST_IP) +#  define HAVE_TEST_IP +#else +#  define TEST_IP               1 +#endif +#if defined(TEST_OP) +#  define HAVE_TEST_OP +#else +#  define TEST_OP               1 +#endif + +#if defined(NEED_IP) +#  define HAVE_NEED_IP +#else +#  define NEED_IP(x)            ((void) 0) +#endif +#if defined(NEED_OP) +#  define HAVE_NEED_OP +#else +#  define NEED_OP(x)            ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +#  define HAVE_ANY_IP +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +#  define HAVE_ANY_OP +#endif + +#undef __COPY4 +#define __COPY4(dst,src)    * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) + +#undef COPY4 +#if defined(LZO_UNALIGNED_OK_4) +#  define COPY4(dst,src)    __COPY4(dst,src) +#elif defined(LZO_ALIGNED_OK_4) +#  define COPY4(dst,src)    __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src)) +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS  ( const lzo_byte *in , lzo_uint  in_len, +		       lzo_byte *out, lzo_uintp out_len, +		       lzo_voidp wrkmem ) +#endif +{ +    register lzo_byte *op; +    register const lzo_byte *ip; +    register lzo_uint t; +#if defined(COPY_DICT) +    lzo_uint m_off; +    const lzo_byte *dict_end; +#else +    register const lzo_byte *m_pos; +#endif + +    const lzo_byte * const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) +    lzo_byte * const op_end = out + *out_len; +#endif +#if defined(LZO1Z) +    lzo_uint last_m_off = 0; +#endif + +    LZO_UNUSED(wrkmem); + +#if defined(__LZO_QUERY_DECOMPRESS) +    if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) +	return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0); +#endif + +#if defined(COPY_DICT) +    if (dict) +    { +	if (dict_len > M4_MAX_OFFSET) +	{ +	    dict += dict_len - M4_MAX_OFFSET; +	    dict_len = M4_MAX_OFFSET; +	} +	dict_end = dict + dict_len; +    } +    else +    { +	dict_len = 0; +	dict_end = NULL; +    } +#endif + +    *out_len = 0; + +    op = out; +    ip = in; + +    if (*ip > 17) +    { +	t = *ip++ - 17; +	if (t < 4) +	    goto match_next; +	assert(t > 0); NEED_OP(t); NEED_IP(t+1); +	do *op++ = *ip++; while (--t > 0); +	goto first_literal_run; +    } + +    while (TEST_IP && TEST_OP) +    { +	t = *ip++; +	if (t >= 16) +	    goto match; +	if (t == 0) +	{ +	    NEED_IP(1); +	    while (*ip == 0) +	    { +		t += 255; +		ip++; +		NEED_IP(1); +	    } +	    t += 15 + *ip++; +	} +	assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) +	if (PTR_ALIGNED2_4(op,ip)) +	{ +#endif +	COPY4(op,ip); +	op += 4; ip += 4; +	if (--t > 0) +	{ +	    if (t >= 4) +	    { +		do { +		    COPY4(op,ip); +		    op += 4; ip += 4; t -= 4; +		} while (t >= 4); +		if (t > 0) do *op++ = *ip++; while (--t > 0); +	    } +	    else +		do *op++ = *ip++; while (--t > 0); +	} +#if !defined(LZO_UNALIGNED_OK_4) +	} +	else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) +	{ +	    *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; +	    do *op++ = *ip++; while (--t > 0); +	} +#endif + +first_literal_run: + +	t = *ip++; +	if (t >= 16) +	    goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) +	m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); +	last_m_off = m_off; +#else +	m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif +	NEED_OP(3); +	t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) +	t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); +	m_pos = op - t; +	last_m_off = t; +#else +	m_pos = op - (1 + M2_MAX_OFFSET); +	m_pos -= t >> 2; +	m_pos -= *ip++ << 2; +#endif +	TEST_LOOKBEHIND(m_pos,out); NEED_OP(3); +	*op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif +	goto match_done; + +	while (TEST_IP && TEST_OP) +	{ +match: +	    if (t >= 64) +	    { +#if defined(COPY_DICT) +#if defined(LZO1X) +		m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); +		t = (t >> 5) - 1; +#elif defined(LZO1Y) +		m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); +		t = (t >> 4) - 3; +#elif defined(LZO1Z) +		m_off = t & 0x1f; +		if (m_off >= 0x1c) +		    m_off = last_m_off; +		else +		{ +		    m_off = 1 + (m_off << 6) + (*ip++ >> 2); +		    last_m_off = m_off; +		} +		t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) +		m_pos = op - 1; +		m_pos -= (t >> 2) & 7; +		m_pos -= *ip++ << 3; +		t = (t >> 5) - 1; +#elif defined(LZO1Y) +		m_pos = op - 1; +		m_pos -= (t >> 2) & 3; +		m_pos -= *ip++ << 2; +		t = (t >> 4) - 3; +#elif defined(LZO1Z) +		{ +		    lzo_uint off = t & 0x1f; +		    m_pos = op; +		    if (off >= 0x1c) +		    { +			assert(last_m_off > 0); +			m_pos -= last_m_off; +		    } +		    else +		    { +			off = 1 + (off << 6) + (*ip++ >> 2); +			m_pos -= off; +			last_m_off = off; +		    } +		} +		t = (t >> 5) - 1; +#endif +		TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1); +		goto copy_match; +#endif +	    } +	    else if (t >= 32) +	    { +		t &= 31; +		if (t == 0) +		{ +		    NEED_IP(1); +		    while (*ip == 0) +		    { +			t += 255; +			ip++; +			NEED_IP(1); +		    } +		    t += 31 + *ip++; +		} +#if defined(COPY_DICT) +#if defined(LZO1Z) +		m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); +		last_m_off = m_off; +#else +		m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) +		{ +		    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); +		    m_pos = op - off; +		    last_m_off = off; +		} +#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) +		m_pos = op - 1; +		m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else +		m_pos = op - 1; +		m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif +		ip += 2; +	    } +	    else if (t >= 16) +	    { +#if defined(COPY_DICT) +		m_off = (t & 8) << 11; +#else +		m_pos = op; +		m_pos -= (t & 8) << 11; +#endif +		t &= 7; +		if (t == 0) +		{ +		    NEED_IP(1); +		    while (*ip == 0) +		    { +			t += 255; +			ip++; +			NEED_IP(1); +		    } +		    t += 7 + *ip++; +		} +#if defined(COPY_DICT) +#if defined(LZO1Z) +		m_off += (ip[0] << 6) + (ip[1] >> 2); +#else +		m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif +		ip += 2; +		if (m_off == 0) +		    goto eof_found; +		m_off += 0x4000; +#if defined(LZO1Z) +		last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) +		m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) +		m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else +		m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +		ip += 2; +		if (m_pos == op) +		    goto eof_found; +		m_pos -= 0x4000; +#if defined(LZO1Z) +		last_m_off = op - m_pos; +#endif +#endif +	    } +	    else +	    { +#if defined(COPY_DICT) +#if defined(LZO1Z) +		m_off = 1 + (t << 6) + (*ip++ >> 2); +		last_m_off = m_off; +#else +		m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif +		NEED_OP(2); +		t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) +		t = 1 + (t << 6) + (*ip++ >> 2); +		m_pos = op - t; +		last_m_off = t; +#else +		m_pos = op - 1; +		m_pos -= t >> 2; +		m_pos -= *ip++ << 2; +#endif +		TEST_LOOKBEHIND(m_pos,out); NEED_OP(2); +		*op++ = *m_pos++; *op++ = *m_pos; +#endif +		goto match_done; +	    } + +#if defined(COPY_DICT) + +	    NEED_OP(t+3-1); +	    t += 3-1; COPY_DICT(t,m_off) + +#else + +	    TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) +	    if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) +	    { +		assert((op - m_pos) >= 4); +#else +	    if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) +	    { +#endif +		COPY4(op,m_pos); +		op += 4; m_pos += 4; t -= 4 - (3 - 1); +		do { +		    COPY4(op,m_pos); +		    op += 4; m_pos += 4; t -= 4; +		} while (t >= 4); +		if (t > 0) do *op++ = *m_pos++; while (--t > 0); +	    } +	    else +#endif +	    { +copy_match: +		*op++ = *m_pos++; *op++ = *m_pos++; +		do *op++ = *m_pos++; while (--t > 0); +	    } + +#endif + +match_done: +#if defined(LZO1Z) +	    t = ip[-1] & 3; +#else +	    t = ip[-2] & 3; +#endif +	    if (t == 0) +		break; + +match_next: +	    assert(t > 0); NEED_OP(t); NEED_IP(t+1); +	    do *op++ = *ip++; while (--t > 0); +	    t = *ip++; +	} +    } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) +    *out_len = op - out; +    return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: +    assert(t == 1); +    *out_len = op - out; +    return (ip == ip_end ? LZO_E_OK : +	   (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: +    *out_len = op - out; +    return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: +    *out_len = op - out; +    return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +lookbehind_overrun: +    *out_len = op - out; +    return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#define LZO_TEST_DECOMPRESS_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS       lzo1x_decompress_safe + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN) +#  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT) +#    define LZO_TEST_DECOMPRESS_OVERRUN_INPUT       2 +#  endif +#  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT) +#    define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT      2 +#  endif +#  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +#    define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND +#  endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LOOKBEHIND +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT) +#  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1) +#    define TEST_IP             (ip < ip_end) +#  endif +#  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2) +#    define NEED_IP(x) \ +	    if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x))  goto input_overrun +#  endif +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT) +#  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1) +#    define TEST_OP             (op <= op_end) +#  endif +#  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2) +#    undef TEST_OP +#    define NEED_OP(x) \ +	    if ((lzo_uint)(op_end - op) < (lzo_uint)(x))  goto output_overrun +#  endif +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +#  define TEST_LOOKBEHIND(m_pos,out)    if (m_pos < out) goto lookbehind_overrun +#else +#  define TEST_LOOKBEHIND(m_pos,op)     ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +#  define TEST_IP               (ip < ip_end) +#endif + +#if defined(TEST_IP) +#  define HAVE_TEST_IP +#else +#  define TEST_IP               1 +#endif +#if defined(TEST_OP) +#  define HAVE_TEST_OP +#else +#  define TEST_OP               1 +#endif + +#if defined(NEED_IP) +#  define HAVE_NEED_IP +#else +#  define NEED_IP(x)            ((void) 0) +#endif +#if defined(NEED_OP) +#  define HAVE_NEED_OP +#else +#  define NEED_OP(x)            ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +#  define HAVE_ANY_IP +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +#  define HAVE_ANY_OP +#endif + +#undef __COPY4 +#define __COPY4(dst,src)    * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) + +#undef COPY4 +#if defined(LZO_UNALIGNED_OK_4) +#  define COPY4(dst,src)    __COPY4(dst,src) +#elif defined(LZO_ALIGNED_OK_4) +#  define COPY4(dst,src)    __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src)) +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS  ( const lzo_byte *in , lzo_uint  in_len, +		       lzo_byte *out, lzo_uintp out_len, +		       lzo_voidp wrkmem ) +#endif +{ +    register lzo_byte *op; +    register const lzo_byte *ip; +    register lzo_uint t; +#if defined(COPY_DICT) +    lzo_uint m_off; +    const lzo_byte *dict_end; +#else +    register const lzo_byte *m_pos; +#endif + +    const lzo_byte * const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) +    lzo_byte * const op_end = out + *out_len; +#endif +#if defined(LZO1Z) +    lzo_uint last_m_off = 0; +#endif + +    LZO_UNUSED(wrkmem); + +#if defined(__LZO_QUERY_DECOMPRESS) +    if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) +	return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0); +#endif + +#if defined(COPY_DICT) +    if (dict) +    { +	if (dict_len > M4_MAX_OFFSET) +	{ +	    dict += dict_len - M4_MAX_OFFSET; +	    dict_len = M4_MAX_OFFSET; +	} +	dict_end = dict + dict_len; +    } +    else +    { +	dict_len = 0; +	dict_end = NULL; +    } +#endif + +    *out_len = 0; + +    op = out; +    ip = in; + +    if (*ip > 17) +    { +	t = *ip++ - 17; +	if (t < 4) +	    goto match_next; +	assert(t > 0); NEED_OP(t); NEED_IP(t+1); +	do *op++ = *ip++; while (--t > 0); +	goto first_literal_run; +    } + +    while (TEST_IP && TEST_OP) +    { +	t = *ip++; +	if (t >= 16) +	    goto match; +	if (t == 0) +	{ +	    NEED_IP(1); +	    while (*ip == 0) +	    { +		t += 255; +		ip++; +		NEED_IP(1); +	    } +	    t += 15 + *ip++; +	} +	assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) +	if (PTR_ALIGNED2_4(op,ip)) +	{ +#endif +	COPY4(op,ip); +	op += 4; ip += 4; +	if (--t > 0) +	{ +	    if (t >= 4) +	    { +		do { +		    COPY4(op,ip); +		    op += 4; ip += 4; t -= 4; +		} while (t >= 4); +		if (t > 0) do *op++ = *ip++; while (--t > 0); +	    } +	    else +		do *op++ = *ip++; while (--t > 0); +	} +#if !defined(LZO_UNALIGNED_OK_4) +	} +	else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) +	{ +	    *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; +	    do *op++ = *ip++; while (--t > 0); +	} +#endif + +first_literal_run: + +	t = *ip++; +	if (t >= 16) +	    goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) +	m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); +	last_m_off = m_off; +#else +	m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif +	NEED_OP(3); +	t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) +	t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); +	m_pos = op - t; +	last_m_off = t; +#else +	m_pos = op - (1 + M2_MAX_OFFSET); +	m_pos -= t >> 2; +	m_pos -= *ip++ << 2; +#endif +	TEST_LOOKBEHIND(m_pos,out); NEED_OP(3); +	*op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif +	goto match_done; + +	while (TEST_IP && TEST_OP) +	{ +match: +	    if (t >= 64) +	    { +#if defined(COPY_DICT) +#if defined(LZO1X) +		m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); +		t = (t >> 5) - 1; +#elif defined(LZO1Y) +		m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); +		t = (t >> 4) - 3; +#elif defined(LZO1Z) +		m_off = t & 0x1f; +		if (m_off >= 0x1c) +		    m_off = last_m_off; +		else +		{ +		    m_off = 1 + (m_off << 6) + (*ip++ >> 2); +		    last_m_off = m_off; +		} +		t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) +		m_pos = op - 1; +		m_pos -= (t >> 2) & 7; +		m_pos -= *ip++ << 3; +		t = (t >> 5) - 1; +#elif defined(LZO1Y) +		m_pos = op - 1; +		m_pos -= (t >> 2) & 3; +		m_pos -= *ip++ << 2; +		t = (t >> 4) - 3; +#elif defined(LZO1Z) +		{ +		    lzo_uint off = t & 0x1f; +		    m_pos = op; +		    if (off >= 0x1c) +		    { +			assert(last_m_off > 0); +			m_pos -= last_m_off; +		    } +		    else +		    { +			off = 1 + (off << 6) + (*ip++ >> 2); +			m_pos -= off; +			last_m_off = off; +		    } +		} +		t = (t >> 5) - 1; +#endif +		TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1); +		goto copy_match; +#endif +	    } +	    else if (t >= 32) +	    { +		t &= 31; +		if (t == 0) +		{ +		    NEED_IP(1); +		    while (*ip == 0) +		    { +			t += 255; +			ip++; +			NEED_IP(1); +		    } +		    t += 31 + *ip++; +		} +#if defined(COPY_DICT) +#if defined(LZO1Z) +		m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); +		last_m_off = m_off; +#else +		m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) +		{ +		    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); +		    m_pos = op - off; +		    last_m_off = off; +		} +#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) +		m_pos = op - 1; +		m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else +		m_pos = op - 1; +		m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif +		ip += 2; +	    } +	    else if (t >= 16) +	    { +#if defined(COPY_DICT) +		m_off = (t & 8) << 11; +#else +		m_pos = op; +		m_pos -= (t & 8) << 11; +#endif +		t &= 7; +		if (t == 0) +		{ +		    NEED_IP(1); +		    while (*ip == 0) +		    { +			t += 255; +			ip++; +			NEED_IP(1); +		    } +		    t += 7 + *ip++; +		} +#if defined(COPY_DICT) +#if defined(LZO1Z) +		m_off += (ip[0] << 6) + (ip[1] >> 2); +#else +		m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif +		ip += 2; +		if (m_off == 0) +		    goto eof_found; +		m_off += 0x4000; +#if defined(LZO1Z) +		last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) +		m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) +		m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else +		m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +		ip += 2; +		if (m_pos == op) +		    goto eof_found; +		m_pos -= 0x4000; +#if defined(LZO1Z) +		last_m_off = op - m_pos; +#endif +#endif +	    } +	    else +	    { +#if defined(COPY_DICT) +#if defined(LZO1Z) +		m_off = 1 + (t << 6) + (*ip++ >> 2); +		last_m_off = m_off; +#else +		m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif +		NEED_OP(2); +		t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) +		t = 1 + (t << 6) + (*ip++ >> 2); +		m_pos = op - t; +		last_m_off = t; +#else +		m_pos = op - 1; +		m_pos -= t >> 2; +		m_pos -= *ip++ << 2; +#endif +		TEST_LOOKBEHIND(m_pos,out); NEED_OP(2); +		*op++ = *m_pos++; *op++ = *m_pos; +#endif +		goto match_done; +	    } + +#if defined(COPY_DICT) + +	    NEED_OP(t+3-1); +	    t += 3-1; COPY_DICT(t,m_off) + +#else + +	    TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) +	    if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) +	    { +		assert((op - m_pos) >= 4); +#else +	    if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) +	    { +#endif +		COPY4(op,m_pos); +		op += 4; m_pos += 4; t -= 4 - (3 - 1); +		do { +		    COPY4(op,m_pos); +		    op += 4; m_pos += 4; t -= 4; +		} while (t >= 4); +		if (t > 0) do *op++ = *m_pos++; while (--t > 0); +	    } +	    else +#endif +	    { +copy_match: +		*op++ = *m_pos++; *op++ = *m_pos++; +		do *op++ = *m_pos++; while (--t > 0); +	    } + +#endif + +match_done: +#if defined(LZO1Z) +	    t = ip[-1] & 3; +#else +	    t = ip[-2] & 3; +#endif +	    if (t == 0) +		break; + +match_next: +	    assert(t > 0); NEED_OP(t); NEED_IP(t+1); +	    do *op++ = *ip++; while (--t > 0); +	    t = *ip++; +	} +    } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) +    *out_len = op - out; +    return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: +    assert(t == 1); +    *out_len = op - out; +    return (ip == ip_end ? LZO_E_OK : +	   (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: +    *out_len = op - out; +    return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: +    *out_len = op - out; +    return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) +lookbehind_overrun: +    *out_len = op - out; +    return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +/***** End of minilzo.c *****/ + diff --git a/3rdParty/LibVNC/src/libvncclient/minilzo.h b/3rdParty/LibVNC/src/libvncclient/minilzo.h new file mode 100644 index 0000000..e3270f9 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/minilzo.h @@ -0,0 +1,100 @@ +/* minilzo.h -- mini subset of the LZO real-time data compression library + +   This file is part of the LZO real-time data compression library. + +   Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer +   Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer +   All Rights Reserved. + +   The LZO library 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. + +   The LZO library 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 the LZO library; see the file COPYING. +   If not, write to the Free Software Foundation, Inc., +   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +   Markus F.X.J. Oberhumer +   <markus@oberhumer.com> +   http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + *   the full LZO package can be found at + *   http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __MINILZO_H +#define __MINILZO_H + +#define MINILZO_VERSION         0x1080 + +#ifdef __LZOCONF_H +#  error "you cannot use both LZO and miniLZO" +#endif + +#undef LZO_HAVE_CONFIG_H +#include "lzoconf.h" + +#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) +#  error "version mismatch in header files" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1X_MEM_COMPRESS      LZO1X_1_MEM_COMPRESS +#define LZO1X_1_MEM_COMPRESS    ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1X_MEM_DECOMPRESS    (0) + + +/* compression */ +LZO_EXTERN(int) +lzo1x_1_compress        ( const lzo_byte *src, lzo_uint  src_len, +                                lzo_byte *dst, lzo_uintp dst_len, +                                lzo_voidp wrkmem ); + +/* decompression */ +LZO_EXTERN(int) +lzo1x_decompress        ( const lzo_byte *src, lzo_uint  src_len, +                                lzo_byte *dst, lzo_uintp dst_len, +                                lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1x_decompress_safe   ( const lzo_byte *src, lzo_uint  src_len, +                                lzo_byte *dst, lzo_uintp dst_len, +                                lzo_voidp wrkmem /* NOT USED */ ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/3rdParty/LibVNC/src/libvncclient/rfbproto.c b/3rdParty/LibVNC/src/libvncclient/rfbproto.c new file mode 100644 index 0000000..33307d2 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/rfbproto.c @@ -0,0 +1,2123 @@ +/* + *  Copyright (C) 2000-2002 Constantin Kaplinsky.  All Rights Reserved. + *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved. + *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved. + * + *  This is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This software is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this software; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, + *  USA. + */ + +/* + * rfbproto.c - functions to deal with client side of RFB protocol. + */ + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#define _POSIX_SOURCE +#endif +#ifndef WIN32 +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#else +#define strncasecmp _strnicmp +#endif +#include <errno.h> +#ifndef WIN32 +#include <pwd.h> +#endif +#include <rfb/rfbclient.h> +#ifdef LIBVNCSERVER_HAVE_LIBZ +#include <zlib.h> +#ifdef __CHECKER__ +#undef Z_NULL +#define Z_NULL NULL +#endif +#endif +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +#include <jpeglib.h> +#endif +#include <stdarg.h> +#include <time.h> + +#include "minilzo.h" +#include "tls.h" + +/* + * rfbClientLog prints a time-stamped message to the log file (stderr). + */ + +rfbBool rfbEnableClientLogging=TRUE; + +static void +rfbDefaultClientLog(const char *format, ...) +{ +    va_list args; +    char buf[256]; +    time_t log_clock; + +    if(!rfbEnableClientLogging) +      return; + +    va_start(args, format); + +    time(&log_clock); +    strftime(buf, 255, "%d/%m/%Y %X ", localtime(&log_clock)); +    fprintf(stderr, "%s", buf); + +    vfprintf(stderr, format, args); +    fflush(stderr); + +    va_end(args); +} + +rfbClientLogProc rfbClientLog=rfbDefaultClientLog; +rfbClientLogProc rfbClientErr=rfbDefaultClientLog; + +/* extensions */ + +rfbClientProtocolExtension* rfbClientExtensions = NULL; + +void rfbClientRegisterExtension(rfbClientProtocolExtension* e) +{ +	e->next = rfbClientExtensions; +	rfbClientExtensions = e; +} + +/* client data */ + +void rfbClientSetClientData(rfbClient* client, void* tag, void* data) +{ +	rfbClientData* clientData = client->clientData; + +	while(clientData && clientData->tag != tag) +		clientData = clientData->next; +	if(clientData == NULL) { +		clientData = calloc(sizeof(rfbClientData), 1); +		clientData->next = client->clientData; +		client->clientData = clientData; +		clientData->tag = tag; +	} + +	clientData->data = data; +} + +void* rfbClientGetClientData(rfbClient* client, void* tag) +{ +	rfbClientData* clientData = client->clientData; + +	while(clientData) { +		if(clientData->tag == tag) +			return clientData->data; +		clientData = clientData->next; +	} + +	return NULL; +} + +/* messages */ + +static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) { +  int i,j; + +#define FILL_RECT(BPP) \ +    for(j=y*client->width;j<(y+h)*client->width;j+=client->width) \ +      for(i=x;i<x+w;i++) \ +	((uint##BPP##_t*)client->frameBuffer)[j+i]=colour; + +  switch(client->format.bitsPerPixel) { +  case  8: FILL_RECT(8);  break; +  case 16: FILL_RECT(16); break; +  case 32: FILL_RECT(32); break; +  default: +    rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); +  } +} + +static void CopyRectangle(rfbClient* client, uint8_t* buffer, int x, int y, int w, int h) { +  int j; + +#define COPY_RECT(BPP) \ +  { \ +    int rs = w * BPP / 8, rs2 = client->width * BPP / 8; \ +    for (j = ((x * (BPP / 8)) + (y * rs2)); j < (y + h) * rs2; j += rs2) { \ +      memcpy(client->frameBuffer + j, buffer, rs); \ +      buffer += rs; \ +    } \ +  } + +  switch(client->format.bitsPerPixel) { +  case  8: COPY_RECT(8);  break; +  case 16: COPY_RECT(16); break; +  case 32: COPY_RECT(32); break; +  default: +    rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); +  } +} + +/* TODO: test */ +static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) { +  int i,j; + +#define COPY_RECT_FROM_RECT(BPP) \ +  { \ +    uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \ +    if (dest_y < src_y) { \ +      for(j = dest_y*client->width; j < (dest_y+h)*client->width; j += client->width) { \ +        if (dest_x < src_x) { \ +          for(i = dest_x; i < dest_x+w; i++) { \ +            ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ +          } \ +        } else { \ +          for(i = dest_x+w-1; i >= dest_x; i--) { \ +            ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ +          } \ +        } \ +      } \ +    } else { \ +      for(j = (dest_y+h-1)*client->width; j >= dest_y*client->width; j-=client->width) { \ +        if (dest_x < src_x) { \ +          for(i = dest_x; i < dest_x+w; i++) { \ +            ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ +          } \ +        } else { \ +          for(i = dest_x+w-1; i >= dest_x; i--) { \ +            ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ +          } \ +        } \ +      } \ +    } \ +  } + +  switch(client->format.bitsPerPixel) { +  case  8: COPY_RECT_FROM_RECT(8);  break; +  case 16: COPY_RECT_FROM_RECT(16); break; +  case 32: COPY_RECT_FROM_RECT(32); break; +  default: +    rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); +  } +} + +static rfbBool HandleRRE8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleRRE16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleRRE32(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleCoRRE8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleCoRRE16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleCoRRE32(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleHextile8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleHextile16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleHextile32(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltra8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltra16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltra32(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltraZip8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltraZip16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltraZip32(rfbClient* client, int rx, int ry, int rw, int rh); +#ifdef LIBVNCSERVER_HAVE_LIBZ +static rfbBool HandleZlib8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZlib16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZlib32(rfbClient* client, int rx, int ry, int rw, int rh); +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +static rfbBool HandleTight8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTight16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTight32(rfbClient* client, int rx, int ry, int rw, int rh); + +static long ReadCompactLen (rfbClient* client); + +static void JpegInitSource(j_decompress_ptr cinfo); +static boolean JpegFillInputBuffer(j_decompress_ptr cinfo); +static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes); +static void JpegTermSource(j_decompress_ptr cinfo); +static void JpegSetSrcManager(j_decompress_ptr cinfo, uint8_t *compressedData, +                              int compressedLen); +#endif +static rfbBool HandleZRLE8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE15(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE24(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE24Up(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE24Down(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE32(rfbClient* client, int rx, int ry, int rw, int rh); +#endif + +/* + * Server Capability Functions + */ +rfbBool +SupportsClient2Server(rfbClient* client, int messageType) +{ +    return (client->supportedMessages.client2server[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE); +} + +rfbBool +SupportsServer2Client(rfbClient* client, int messageType) +{ +    return (client->supportedMessages.server2client[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE); +} + +void +SetClient2Server(rfbClient* client, int messageType) +{ +  client->supportedMessages.client2server[((messageType & 0xFF)/8)] |= (1<<(messageType % 8)); +} + +void +SetServer2Client(rfbClient* client, int messageType) +{ +  client->supportedMessages.server2client[((messageType & 0xFF)/8)] |= (1<<(messageType % 8)); +} + +void +ClearClient2Server(rfbClient* client, int messageType) +{ +  client->supportedMessages.client2server[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8))); +} + +void +ClearServer2Client(rfbClient* client, int messageType) +{ +  client->supportedMessages.server2client[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8))); +} + + +void +DefaultSupportedMessages(rfbClient* client) +{ +    memset((char *)&client->supportedMessages,0,sizeof(client->supportedMessages)); + +    /* Default client supported messages (universal RFB 3.3 protocol) */ +    SetClient2Server(client, rfbSetPixelFormat); +    /* SetClient2Server(client, rfbFixColourMapEntries); Not currently supported */ +    SetClient2Server(client, rfbSetEncodings); +    SetClient2Server(client, rfbFramebufferUpdateRequest); +    SetClient2Server(client, rfbKeyEvent); +    SetClient2Server(client, rfbPointerEvent); +    SetClient2Server(client, rfbClientCutText); +    /* technically, we only care what we can *send* to the server +     * but, we set Server2Client Just in case it ever becomes useful +     */ +    SetServer2Client(client, rfbFramebufferUpdate); +    SetServer2Client(client, rfbSetColourMapEntries); +    SetServer2Client(client, rfbBell); +    SetServer2Client(client, rfbServerCutText); +} + +void +DefaultSupportedMessagesUltraVNC(rfbClient* client) +{ +    DefaultSupportedMessages(client); +    SetClient2Server(client, rfbFileTransfer); +    SetClient2Server(client, rfbSetScale); +    SetClient2Server(client, rfbSetServerInput); +    SetClient2Server(client, rfbSetSW); +    SetClient2Server(client, rfbTextChat); +    SetClient2Server(client, rfbPalmVNCSetScaleFactor); +    /* technically, we only care what we can *send* to the server */ +    SetServer2Client(client, rfbResizeFrameBuffer); +    SetServer2Client(client, rfbPalmVNCReSizeFrameBuffer); +    SetServer2Client(client, rfbFileTransfer); +    SetServer2Client(client, rfbTextChat); +} + + +void +DefaultSupportedMessagesTightVNC(rfbClient* client) +{ +    DefaultSupportedMessages(client); +    SetClient2Server(client, rfbFileTransfer); +    SetClient2Server(client, rfbSetServerInput); +    SetClient2Server(client, rfbSetSW); +    /* SetClient2Server(client, rfbTextChat); */ +    /* technically, we only care what we can *send* to the server */ +    SetServer2Client(client, rfbFileTransfer); +    SetServer2Client(client, rfbTextChat); +} + +#ifndef WIN32 +static rfbBool +IsUnixSocket(const char *name) +{ +  struct stat sb; +  if(stat(name, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFSOCK) +    return TRUE; +  return FALSE; +} +#endif + +/* + * ConnectToRFBServer. + */ + +rfbBool +ConnectToRFBServer(rfbClient* client,const char *hostname, int port) +{ +  unsigned int host; + +  if (client->serverPort==-1) { +    /* serverHost is a file recorded by vncrec. */ +    const char* magic="vncLog0.0"; +    char buffer[10]; +    rfbVNCRec* rec = (rfbVNCRec*)malloc(sizeof(rfbVNCRec)); +    client->vncRec = rec; + +    rec->file = fopen(client->serverHost,"rb"); +    rec->tv.tv_sec = 0; +    rec->readTimestamp = FALSE; +    rec->doNotSleep = FALSE; +     +    if (!rec->file) { +      rfbClientLog("Could not open %s.\n",client->serverHost); +      return FALSE; +    } +    setbuf(rec->file,NULL); +    fread(buffer,1,strlen(magic),rec->file); +    if (strncmp(buffer,magic,strlen(magic))) { +      rfbClientLog("File %s was not recorded by vncrec.\n",client->serverHost); +      fclose(rec->file); +      return FALSE; +    } +    client->sock = -1; +    return TRUE; +  } + +#ifndef WIN32 +  if(IsUnixSocket(hostname)) +    /* serverHost is a UNIX socket. */ +    client->sock = ConnectClientToUnixSock(hostname); +  else +#endif +  { +    /* serverHost is a hostname */ +    if (!StringToIPAddr(hostname, &host)) { +      rfbClientLog("Couldn't convert '%s' to host address\n", hostname); +      return FALSE; +    } +    client->sock = ConnectClientToTcpAddr(host, port); +  } + +  if (client->sock < 0) { +    rfbClientLog("Unable to connect to VNC server\n"); +    return FALSE; +  } + +  return SetNonBlocking(client->sock); +} + +/* + * ConnectToRFBRepeater. + */ + +rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort) +{ +  unsigned int host; +  rfbProtocolVersionMsg pv; +  int major,minor; +  char tmphost[250]; + +  if (!StringToIPAddr(repeaterHost, &host)) { +    rfbClientLog("Couldn't convert '%s' to host address\n", repeaterHost); +    return FALSE; +  } + +  client->sock = ConnectClientToTcpAddr(host, repeaterPort); + +  if (client->sock < 0) { +    rfbClientLog("Unable to connect to VNC repeater\n"); +    return FALSE; +  } + +  if (!SetNonBlocking(client->sock)) +    return FALSE; + +  if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) +    return FALSE; +  pv[sz_rfbProtocolVersionMsg] = 0; + +  /* UltraVNC repeater always report version 000.000 to identify itself */ +  if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2 || major != 0 || minor != 0) { +    rfbClientLog("Not a valid VNC repeater (%s)\n",pv); +    return FALSE; +  } + +  rfbClientLog("Connected to VNC repeater, using protocol version %d.%d\n", major, minor); + +  snprintf(tmphost, sizeof(tmphost), "%s:%d", destHost, destPort); +  if (!WriteToRFBServer(client, tmphost, sizeof(tmphost))) +    return FALSE; + +  return TRUE; +} + +extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd); +extern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key); + +rfbBool +rfbHandleAuthResult(rfbClient* client) +{ +    uint32_t authResult=0, reasonLen=0; +    char *reason=NULL; + +    if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE; + +    authResult = rfbClientSwap32IfLE(authResult); + +    switch (authResult) { +    case rfbVncAuthOK: +      rfbClientLog("VNC authentication succeeded\n"); +      return TRUE; +      break; +    case rfbVncAuthFailed: +      if (client->major==3 && client->minor>7) +      { +        /* we have an error following */ +        if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE; +        reasonLen = rfbClientSwap32IfLE(reasonLen); +        reason = malloc(reasonLen+1); +        if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; } +        reason[reasonLen]=0; +        rfbClientLog("VNC connection failed: %s\n",reason); +        free(reason); +        return FALSE; +      } +      rfbClientLog("VNC authentication failed\n"); +      return FALSE; +    case rfbVncAuthTooMany: +      rfbClientLog("VNC authentication failed - too many tries\n"); +      return FALSE; +    } + +    rfbClientLog("Unknown VNC authentication result: %d\n", +                 (int)authResult); +    return FALSE; +} + +static void +ReadReason(rfbClient* client) +{ +    uint32_t reasonLen; +    char *reason; + +    /* we have an error following */ +    if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return; +    reasonLen = rfbClientSwap32IfLE(reasonLen); +    reason = malloc(reasonLen+1); +    if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; } +    reason[reasonLen]=0; +    rfbClientLog("VNC connection failed: %s\n",reason); +    free(reason); +} + +static rfbBool +ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth) +{ +    uint8_t count=0; +    uint8_t loop=0; +    uint8_t flag=0; +    uint8_t tAuth[256]; +    char buf1[500],buf2[10]; +    uint32_t authScheme; + +    if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE; + +    if (count==0) +    { +        rfbClientLog("List of security types is ZERO, expecting an error to follow\n"); +        ReadReason(client); +        return FALSE; +    } +    if (count>sizeof(tAuth)) +    { +        rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth)); +        return FALSE; +    } + +    rfbClientLog("We have %d security types to read\n", count); +    authScheme=0; +    /* now, we have a list of available security types to read ( uint8_t[] ) */ +    for (loop=0;loop<count;loop++) +    { +        if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE; +        rfbClientLog("%d) Received security type %d\n", loop, tAuth[loop]); +        if (flag) continue; +        if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth || tAuth[loop]==rfbMSLogon || +            (!subAuth && (tAuth[loop]==rfbTLS || tAuth[loop]==rfbVeNCrypt))) +        { +            if (!subAuth && client->clientAuthSchemes) +            { +                int i; +                for (i=0;client->clientAuthSchemes[i];i++) +                { +                    if (client->clientAuthSchemes[i]==(uint32_t)tAuth[loop]) +                    { +                        flag++; +                        authScheme=tAuth[loop]; +                        break; +                    } +                } +            } +            else +            { +                flag++; +                authScheme=tAuth[loop]; +            } +            if (flag) +            { +                rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count); +                /* send back a single byte indicating which security type to use */ +                if (!WriteToRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE; +            } +        } +    } +    if (authScheme==0) +    { +        memset(buf1, 0, sizeof(buf1)); +        for (loop=0;loop<count;loop++) +        { +            if (strlen(buf1)>=sizeof(buf1)-1) break; +            snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]); +            strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1); +        } +        rfbClientLog("Unknown authentication scheme from VNC server: %s\n", +               buf1); +        return FALSE; +    } +    *result = authScheme; +    return TRUE; +} + +static rfbBool +HandleVncAuth(rfbClient *client) +{ +    uint8_t challenge[CHALLENGESIZE]; +    char *passwd=NULL; +    int i; + +    if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE; + +    if (client->serverPort!=-1) { /* if not playing a vncrec file */ +      if (client->GetPassword) +        passwd = client->GetPassword(client); + +      if ((!passwd) || (strlen(passwd) == 0)) { +        rfbClientLog("Reading password failed\n"); +        return FALSE; +      } +      if (strlen(passwd) > 8) { +        passwd[8] = '\0'; +      } + +      rfbClientEncryptBytes(challenge, passwd); + +      /* Lose the password from memory */ +      for (i = strlen(passwd); i >= 0; i--) { +        passwd[i] = '\0'; +      } +      free(passwd); + +      if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE; +    } + +    /* Handle the SecurityResult message */ +    if (!rfbHandleAuthResult(client)) return FALSE; + +    return TRUE; +} + +static void +FreeUserCredential(rfbCredential *cred) +{ +  if (cred->userCredential.username) free(cred->userCredential.username); +  if (cred->userCredential.password) free(cred->userCredential.password); +  free(cred); +} + +static rfbBool +HandlePlainAuth(rfbClient *client) +{ +  uint32_t ulen, ulensw; +  uint32_t plen, plensw; +  rfbCredential *cred; + +  if (!client->GetCredential) +  { +    rfbClientLog("GetCredential callback is not set.\n"); +    return FALSE; +  } +  cred = client->GetCredential(client, rfbCredentialTypeUser); +  if (!cred) +  { +    rfbClientLog("Reading credential failed\n"); +    return FALSE; +  } + +  ulen = (cred->userCredential.username ? strlen(cred->userCredential.username) : 0); +  ulensw = rfbClientSwap32IfLE(ulen); +  plen = (cred->userCredential.password ? strlen(cred->userCredential.password) : 0); +  plensw = rfbClientSwap32IfLE(plen); +  if (!WriteToRFBServer(client, (char *)&ulensw, 4) || +      !WriteToRFBServer(client, (char *)&plensw, 4)) +  { +    FreeUserCredential(cred); +    return FALSE; +  } +  if (ulen > 0) +  { +    if (!WriteToRFBServer(client, cred->userCredential.username, ulen)) +    { +      FreeUserCredential(cred); +      return FALSE; +    } +  } +  if (plen > 0) +  { +    if (!WriteToRFBServer(client, cred->userCredential.password, plen)) +    { +      FreeUserCredential(cred); +      return FALSE; +    } +  } + +  FreeUserCredential(cred); + +  /* Handle the SecurityResult message */ +  if (!rfbHandleAuthResult(client)) return FALSE; + +  return TRUE; +} + +/* Simple 64bit big integer arithmetic implementation */ +/* (x + y) % m, works even if (x + y) > 64bit */ +#define rfbAddM64(x,y,m) ((x+y)%m+(x+y<x?(((uint64_t)-1)%m+1)%m:0)) +/* (x * y) % m */ +static uint64_t +rfbMulM64(uint64_t x, uint64_t y, uint64_t m) +{ +  uint64_t r; +  for(r=0;x>0;x>>=1) +  { +    if (x&1) r=rfbAddM64(r,y,m); +    y=rfbAddM64(y,y,m); +  } +  return r; +} +/* (x ^ y) % m */ +static uint64_t +rfbPowM64(uint64_t b, uint64_t e, uint64_t m) +{ +  uint64_t r; +  for(r=1;e>0;e>>=1) +  { +    if(e&1) r=rfbMulM64(r,b,m); +    b=rfbMulM64(b,b,m); +  } +  return r; +} + +static rfbBool +HandleMSLogonAuth(rfbClient *client) +{ +  uint64_t gen, mod, resp, priv, pub, key; +  uint8_t username[256], password[64]; +  rfbCredential *cred; + +  if (!ReadFromRFBServer(client, (char *)&gen, 8)) return FALSE; +  if (!ReadFromRFBServer(client, (char *)&mod, 8)) return FALSE; +  if (!ReadFromRFBServer(client, (char *)&resp, 8)) return FALSE; +  gen = rfbClientSwap64IfLE(gen); +  mod = rfbClientSwap64IfLE(mod); +  resp = rfbClientSwap64IfLE(resp); + +  if (!client->GetCredential) +  { +    rfbClientLog("GetCredential callback is not set.\n"); +    return FALSE; +  } +  rfbClientLog("WARNING! MSLogon security type has very low password encryption! "\ +    "Use it only with SSH tunnel or trusted network.\n"); +  cred = client->GetCredential(client, rfbCredentialTypeUser); +  if (!cred) +  { +    rfbClientLog("Reading credential failed\n"); +    return FALSE; +  } + +  memset(username, 0, sizeof(username)); +  strncpy((char *)username, cred->userCredential.username, sizeof(username)); +  memset(password, 0, sizeof(password)); +  strncpy((char *)password, cred->userCredential.password, sizeof(password)); +  FreeUserCredential(cred); + +  srand(time(NULL)); +  priv = ((uint64_t)rand())<<32; +  priv |= (uint64_t)rand(); + +  pub = rfbPowM64(gen, priv, mod); +  key = rfbPowM64(resp, priv, mod); +  pub = rfbClientSwap64IfLE(pub); +  key = rfbClientSwap64IfLE(key); + +  rfbClientEncryptBytes2(username, sizeof(username), (unsigned char *)&key); +  rfbClientEncryptBytes2(password, sizeof(password), (unsigned char *)&key); + +  if (!WriteToRFBServer(client, (char *)&pub, 8)) return FALSE; +  if (!WriteToRFBServer(client, (char *)username, sizeof(username))) return FALSE; +  if (!WriteToRFBServer(client, (char *)password, sizeof(password))) return FALSE; + +  /* Handle the SecurityResult message */ +  if (!rfbHandleAuthResult(client)) return FALSE; + +  return TRUE; +} + +/* + * SetClientAuthSchemes. + */ + +void +SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size) +{ +  int i; + +  if (client->clientAuthSchemes) +  { +    free(client->clientAuthSchemes); +    client->clientAuthSchemes = NULL; +  } +  if (authSchemes) +  { +    if (size<0) +    { +      /* If size<0 we assume the passed-in list is also 0-terminate, so we +       * calculate the size here */ +      for (size=0;authSchemes[size];size++) ; +    } +    client->clientAuthSchemes = (uint32_t*)malloc(sizeof(uint32_t)*(size+1)); +    for (i=0;i<size;i++) +      client->clientAuthSchemes[i] = authSchemes[i]; +    client->clientAuthSchemes[size] = 0; +  } +} + +/* + * InitialiseRFBConnection. + */ + +rfbBool +InitialiseRFBConnection(rfbClient* client) +{ +  rfbProtocolVersionMsg pv; +  int major,minor; +  uint32_t authScheme; +  uint32_t subAuthScheme; +  rfbClientInitMsg ci; + +  /* if the connection is immediately closed, don't report anything, so +       that pmw's monitor can make test connections */ + +  if (client->listenSpecified) +    errorMessageOnReadFailure = FALSE; + +  if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE; +  pv[sz_rfbProtocolVersionMsg]=0; + +  errorMessageOnReadFailure = TRUE; + +  pv[sz_rfbProtocolVersionMsg] = 0; + +  if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) { +    rfbClientLog("Not a valid VNC server (%s)\n",pv); +    return FALSE; +  } + + +  DefaultSupportedMessages(client); +  client->major = major; +  client->minor = minor; + +  /* fall back to viewer supported version */ +  if ((major==rfbProtocolMajorVersion) && (minor>rfbProtocolMinorVersion)) +    client->minor = rfbProtocolMinorVersion; + +  /* UltraVNC uses minor codes 4 and 6 for the server */ +  if (major==3 && (minor==4 || minor==6)) { +      rfbClientLog("UltraVNC server detected, enabling UltraVNC specific messages\n",pv); +      DefaultSupportedMessagesUltraVNC(client); +  } + +  /* TightVNC uses minor codes 5 for the server */ +  if (major==3 && minor==5) { +      rfbClientLog("TightVNC server detected, enabling TightVNC specific messages\n",pv); +      DefaultSupportedMessagesTightVNC(client); +  } + +  /* we do not support > RFB3.8 */ +  if ((major==3 && minor>8) || major>3) +  { +    client->major=3; +    client->minor=8; +  } + +  rfbClientLog("VNC server supports protocol version %d.%d (viewer %d.%d)\n", +	  major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion); + +  sprintf(pv,rfbProtocolVersionFormat,client->major,client->minor); + +  if (!WriteToRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE; + + +  /* 3.7 and onwards sends a # of security types first */ +  if (client->major==3 && client->minor > 6) +  { +    if (!ReadSupportedSecurityType(client, &authScheme, FALSE)) return FALSE; +  } +  else +  { +    if (!ReadFromRFBServer(client, (char *)&authScheme, 4)) return FALSE; +    authScheme = rfbClientSwap32IfLE(authScheme); +  } +   +  rfbClientLog("Selected Security Scheme %d\n", authScheme); +  client->authScheme = authScheme; +   +  switch (authScheme) { + +  case rfbConnFailed: +    ReadReason(client); +    return FALSE; + +  case rfbNoAuth: +    rfbClientLog("No authentication needed\n"); + +    /* 3.8 and upwards sends a Security Result for rfbNoAuth */ +    if ((client->major==3 && client->minor > 7) || client->major>3) +        if (!rfbHandleAuthResult(client)) return FALSE;         + +    break; + +  case rfbVncAuth: +    if (!HandleVncAuth(client)) return FALSE; +    break; + +  case rfbMSLogon: +    if (!HandleMSLogonAuth(client)) return FALSE; +    break; + +  case rfbTLS: +#ifndef LIBVNCSERVER_WITH_CLIENT_TLS +    rfbClientLog("TLS support was not compiled in\n"); +    return FALSE; +#else +    if (!HandleAnonTLSAuth(client)) return FALSE; +    /* After the TLS session is established, sub auth types are expected. +     * Note that all following reading/writing are through the TLS session from here. +     */ +    if (!ReadSupportedSecurityType(client, &subAuthScheme, TRUE)) return FALSE; +    client->subAuthScheme = subAuthScheme; + +    switch (subAuthScheme) { + +      case rfbConnFailed: +        ReadReason(client); +        return FALSE; + +      case rfbNoAuth: +        rfbClientLog("No sub authentication needed\n"); +        /* 3.8 and upwards sends a Security Result for rfbNoAuth */ +        if ((client->major==3 && client->minor > 7) || client->major>3) +            if (!rfbHandleAuthResult(client)) return FALSE; +        break; + +      case rfbVncAuth: +        if (!HandleVncAuth(client)) return FALSE; +        break; + +      default: +        rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n", +            (int)subAuthScheme); +        return FALSE; +    } +#endif + +    break; + +  case rfbVeNCrypt: +#ifndef LIBVNCSERVER_WITH_CLIENT_TLS +    rfbClientLog("TLS support was not compiled in\n"); +    return FALSE; +#else +    if (!HandleVeNCryptAuth(client)) return FALSE; + +    switch (client->subAuthScheme) { + +      case rfbVeNCryptTLSNone: +      case rfbVeNCryptX509None: +        rfbClientLog("No sub authentication needed\n"); +        if (!rfbHandleAuthResult(client)) return FALSE; +        break; + +      case rfbVeNCryptTLSVNC: +      case rfbVeNCryptX509VNC: +        if (!HandleVncAuth(client)) return FALSE; +        break; + +      case rfbVeNCryptTLSPlain: +      case rfbVeNCryptX509Plain: +        if (!HandlePlainAuth(client)) return FALSE; +        break; + +      default: +        rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n", +            client->subAuthScheme); +        return FALSE; +    } +#endif +    break; + +  default: +    rfbClientLog("Unknown authentication scheme from VNC server: %d\n", +	    (int)authScheme); +    return FALSE; +  } + +  ci.shared = (client->appData.shareDesktop ? 1 : 0); + +  if (!WriteToRFBServer(client,  (char *)&ci, sz_rfbClientInitMsg)) return FALSE; + +  if (!ReadFromRFBServer(client, (char *)&client->si, sz_rfbServerInitMsg)) return FALSE; + +  client->si.framebufferWidth = rfbClientSwap16IfLE(client->si.framebufferWidth); +  client->si.framebufferHeight = rfbClientSwap16IfLE(client->si.framebufferHeight); +  client->si.format.redMax = rfbClientSwap16IfLE(client->si.format.redMax); +  client->si.format.greenMax = rfbClientSwap16IfLE(client->si.format.greenMax); +  client->si.format.blueMax = rfbClientSwap16IfLE(client->si.format.blueMax); +  client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength); + +  client->desktopName = malloc(client->si.nameLength + 1); +  if (!client->desktopName) { +    rfbClientLog("Error allocating memory for desktop name, %lu bytes\n", +            (unsigned long)client->si.nameLength); +    return FALSE; +  } + +  if (!ReadFromRFBServer(client, client->desktopName, client->si.nameLength)) return FALSE; + +  client->desktopName[client->si.nameLength] = 0; + +  rfbClientLog("Desktop name \"%s\"\n",client->desktopName); + +  rfbClientLog("Connected to VNC server, using protocol version %d.%d\n", +	  client->major, client->minor); + +  rfbClientLog("VNC server default format:\n"); +  PrintPixelFormat(&client->si.format); + +  return TRUE; +} + + +/* + * SetFormatAndEncodings. + */ + +rfbBool +SetFormatAndEncodings(rfbClient* client) +{ +  rfbSetPixelFormatMsg spf; +  char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4]; + +  rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf; +  uint32_t *encs = (uint32_t *)(&buf[sz_rfbSetEncodingsMsg]); +  int len = 0; +  rfbBool requestCompressLevel = FALSE; +  rfbBool requestQualityLevel = FALSE; +  rfbBool requestLastRectEncoding = FALSE; +  rfbClientProtocolExtension* e; + +  if (!SupportsClient2Server(client, rfbSetPixelFormat)) return TRUE; + +  spf.type = rfbSetPixelFormat; +  spf.format = client->format; +  spf.format.redMax = rfbClientSwap16IfLE(spf.format.redMax); +  spf.format.greenMax = rfbClientSwap16IfLE(spf.format.greenMax); +  spf.format.blueMax = rfbClientSwap16IfLE(spf.format.blueMax); + +  if (!WriteToRFBServer(client, (char *)&spf, sz_rfbSetPixelFormatMsg)) +    return FALSE; + + +  if (!SupportsClient2Server(client, rfbSetEncodings)) return TRUE; + +  se->type = rfbSetEncodings; +  se->nEncodings = 0; + +  if (client->appData.encodingsString) { +    const char *encStr = client->appData.encodingsString; +    int encStrLen; +    do { +      const char *nextEncStr = strchr(encStr, ' '); +      if (nextEncStr) { +	encStrLen = nextEncStr - encStr; +	nextEncStr++; +      } else { +	encStrLen = strlen(encStr); +      } + +      if (strncasecmp(encStr,"raw",encStrLen) == 0) { +	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw); +      } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) { +	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect); +#ifdef LIBVNCSERVER_HAVE_LIBZ +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +      } else if (strncasecmp(encStr,"tight",encStrLen) == 0) { +	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight); +	requestLastRectEncoding = TRUE; +	if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) +	  requestCompressLevel = TRUE; +	if (client->appData.enableJPEG) +	  requestQualityLevel = TRUE; +#endif +#endif +      } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) { +	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile); +#ifdef LIBVNCSERVER_HAVE_LIBZ +      } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) { +	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib); +	if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) +	  requestCompressLevel = TRUE; +      } else if (strncasecmp(encStr,"zlibhex",encStrLen) == 0) { +	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlibHex); +	if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) +	  requestCompressLevel = TRUE; +      } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) { +	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE); +      } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) { +	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE); +	requestQualityLevel = TRUE; +#endif +      } else if ((strncasecmp(encStr,"ultra",encStrLen) == 0) || (strncasecmp(encStr,"ultrazip",encStrLen) == 0)) { +        /* There are 2 encodings used in 'ultra' */ +        encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra); +        encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip); +      } else if (strncasecmp(encStr,"corre",encStrLen) == 0) { +	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE); +      } else if (strncasecmp(encStr,"rre",encStrLen) == 0) { +	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE); +      } else { +	rfbClientLog("Unknown encoding '%.*s'\n",encStrLen,encStr); +      } + +      encStr = nextEncStr; +    } while (encStr && se->nEncodings < MAX_ENCODINGS); + +    if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) { +      encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel + +					  rfbEncodingCompressLevel0); +    } + +    if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) { +      if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9) +        client->appData.qualityLevel = 5; +      encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel + +					  rfbEncodingQualityLevel0); +    } +  } +  else { +    if (SameMachine(client->sock)) { +      /* TODO: +      if (!tunnelSpecified) { +      */ +      rfbClientLog("Same machine: preferring raw encoding\n"); +      encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw); +      /* +      } else { +	rfbClientLog("Tunneling active: preferring tight encoding\n"); +      } +      */ +    } + +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect); +#ifdef LIBVNCSERVER_HAVE_LIBZ +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight); +    requestLastRectEncoding = TRUE; +#endif +#endif +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile); +#ifdef LIBVNCSERVER_HAVE_LIBZ +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib); +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE); +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE); +#endif +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra); +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip); +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE); +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE); + +    if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) { +      encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel + +					  rfbEncodingCompressLevel0); +    } else /* if (!tunnelSpecified) */ { +      /* If -tunnel option was provided, we assume that server machine is +	 not in the local network so we use default compression level for +	 tight encoding instead of fast compression. Thus we are +	 requesting level 1 compression only if tunneling is not used. */ +      encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCompressLevel1); +    } + +    if (client->appData.enableJPEG) { +      if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9) +	client->appData.qualityLevel = 5; +      encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel + +					  rfbEncodingQualityLevel0); +    } +  } + + + +  /* Remote Cursor Support (local to viewer) */ +  if (client->appData.useRemoteCursor) { +    if (se->nEncodings < MAX_ENCODINGS) +      encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor); +    if (se->nEncodings < MAX_ENCODINGS) +      encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRichCursor); +    if (se->nEncodings < MAX_ENCODINGS) +      encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos); +  } + +  /* Keyboard State Encodings */ +  if (se->nEncodings < MAX_ENCODINGS) +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState); + +  /* New Frame Buffer Size */ +  if (se->nEncodings < MAX_ENCODINGS && client->canHandleNewFBSize) +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNewFBSize); + +  /* Last Rect */ +  if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect); + +  /* Server Capabilities */ +  if (se->nEncodings < MAX_ENCODINGS) +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedMessages); +  if (se->nEncodings < MAX_ENCODINGS) +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedEncodings); +  if (se->nEncodings < MAX_ENCODINGS) +    encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingServerIdentity); + + +  /* client extensions */ +  for(e = rfbClientExtensions; e; e = e->next) +    if(e->encodings) { +      int* enc; +      for(enc = e->encodings; *enc; enc++) +	encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc); +    } + +  len = sz_rfbSetEncodingsMsg + se->nEncodings * 4; + +  se->nEncodings = rfbClientSwap16IfLE(se->nEncodings); + +  if (!WriteToRFBServer(client, buf, len)) return FALSE; + +  return TRUE; +} + + +/* + * SendIncrementalFramebufferUpdateRequest. + */ + +rfbBool +SendIncrementalFramebufferUpdateRequest(rfbClient* client) +{ +	return SendFramebufferUpdateRequest(client, +			client->updateRect.x, client->updateRect.y, +			client->updateRect.w, client->updateRect.h, TRUE); +} + + +/* + * SendFramebufferUpdateRequest. + */ + +rfbBool +SendFramebufferUpdateRequest(rfbClient* client, int x, int y, int w, int h, rfbBool incremental) +{ +  rfbFramebufferUpdateRequestMsg fur; + +  if (!SupportsClient2Server(client, rfbFramebufferUpdateRequest)) return TRUE; +   +  fur.type = rfbFramebufferUpdateRequest; +  fur.incremental = incremental ? 1 : 0; +  fur.x = rfbClientSwap16IfLE(x); +  fur.y = rfbClientSwap16IfLE(y); +  fur.w = rfbClientSwap16IfLE(w); +  fur.h = rfbClientSwap16IfLE(h); + +  if (!WriteToRFBServer(client, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg)) +    return FALSE; + +  return TRUE; +} + + +/* + * SendScaleSetting. + */ +rfbBool +SendScaleSetting(rfbClient* client,int scaleSetting) +{ +  rfbSetScaleMsg ssm; + +  ssm.scale = scaleSetting; +  ssm.pad = 0; +   +  /* favor UltraVNC SetScale if both are supported */ +  if (SupportsClient2Server(client, rfbSetScale)) { +      ssm.type = rfbSetScale; +      if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg)) +          return FALSE; +  } +   +  if (SupportsClient2Server(client, rfbPalmVNCSetScaleFactor)) { +      ssm.type = rfbPalmVNCSetScaleFactor; +      if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg)) +          return FALSE; +  } + +  return TRUE; +} + +/* + * TextChatFunctions (UltraVNC) + * Extremely bandwidth friendly method of communicating with a user + * (Think HelpDesk type applications) + */ + +rfbBool TextChatSend(rfbClient* client, char *text) +{ +    rfbTextChatMsg chat; +    int count = strlen(text); + +    if (!SupportsClient2Server(client, rfbTextChat)) return TRUE; +    chat.type = rfbTextChat; +    chat.pad1 = 0; +    chat.pad2 = 0; +    chat.length = (uint32_t)count; +    chat.length = rfbClientSwap32IfLE(chat.length); + +    if (!WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg)) +        return FALSE; + +    if (count>0) { +        if (!WriteToRFBServer(client, text, count)) +            return FALSE; +    } +    return TRUE; +} + +rfbBool TextChatOpen(rfbClient* client) +{ +    rfbTextChatMsg chat; + +    if (!SupportsClient2Server(client, rfbTextChat)) return TRUE; +    chat.type = rfbTextChat; +    chat.pad1 = 0; +    chat.pad2 = 0; +    chat.length = rfbClientSwap32IfLE(rfbTextChatOpen); +    return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE); +} + +rfbBool TextChatClose(rfbClient* client) +{ +    rfbTextChatMsg chat; +    if (!SupportsClient2Server(client, rfbTextChat)) return TRUE; +    chat.type = rfbTextChat; +    chat.pad1 = 0; +    chat.pad2 = 0; +    chat.length = rfbClientSwap32IfLE(rfbTextChatClose); +    return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE); +} + +rfbBool TextChatFinish(rfbClient* client) +{ +    rfbTextChatMsg chat; +    if (!SupportsClient2Server(client, rfbTextChat)) return TRUE; +    chat.type = rfbTextChat; +    chat.pad1 = 0; +    chat.pad2 = 0; +    chat.length = rfbClientSwap32IfLE(rfbTextChatFinished); +    return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE); +} + +/* + * UltraVNC Server Input Disable + * Apparently, the remote client can *prevent* the local user from interacting with the display + * I would think this is extremely helpful when used in a HelpDesk situation + */ +rfbBool PermitServerInput(rfbClient* client, int enabled) +{ +    rfbSetServerInputMsg msg; + +    if (!SupportsClient2Server(client, rfbSetServerInput)) return TRUE; +    /* enabled==1, then server input from local keyboard is disabled */ +    msg.type = rfbSetServerInput; +    msg.status = (enabled ? 1 : 0); +    msg.pad = 0; +    return  (WriteToRFBServer(client, (char *)&msg, sz_rfbSetServerInputMsg) ? TRUE : FALSE); +} + + +/* + * SendPointerEvent. + */ + +rfbBool +SendPointerEvent(rfbClient* client,int x, int y, int buttonMask) +{ +  rfbPointerEventMsg pe; + +  if (!SupportsClient2Server(client, rfbPointerEvent)) return TRUE; + +  pe.type = rfbPointerEvent; +  pe.buttonMask = buttonMask; +  if (x < 0) x = 0; +  if (y < 0) y = 0; + +  pe.x = rfbClientSwap16IfLE(x); +  pe.y = rfbClientSwap16IfLE(y); +  return WriteToRFBServer(client, (char *)&pe, sz_rfbPointerEventMsg); +} + + +/* + * SendKeyEvent. + */ + +rfbBool +SendKeyEvent(rfbClient* client, uint32_t key, rfbBool down) +{ +  rfbKeyEventMsg ke; + +  if (!SupportsClient2Server(client, rfbKeyEvent)) return TRUE; + +  ke.type = rfbKeyEvent; +  ke.down = down ? 1 : 0; +  ke.key = rfbClientSwap32IfLE(key); +  return WriteToRFBServer(client, (char *)&ke, sz_rfbKeyEventMsg); +} + + +/* + * SendClientCutText. + */ + +rfbBool +SendClientCutText(rfbClient* client, char *str, int len) +{ +  rfbClientCutTextMsg cct; + +  if (!SupportsClient2Server(client, rfbClientCutText)) return TRUE; + +  cct.type = rfbClientCutText; +  cct.length = rfbClientSwap32IfLE(len); +  return  (WriteToRFBServer(client, (char *)&cct, sz_rfbClientCutTextMsg) && +	   WriteToRFBServer(client, str, len)); +} + + + +/* + * HandleRFBServerMessage. + */ + +rfbBool +HandleRFBServerMessage(rfbClient* client) +{ +  rfbServerToClientMsg msg; + +  if (client->serverPort==-1) +    client->vncRec->readTimestamp = TRUE; +  if (!ReadFromRFBServer(client, (char *)&msg, 1)) +    return FALSE; + +  switch (msg.type) { + +  case rfbSetColourMapEntries: +  { +    /* TODO: +    int i; +    uint16_t rgb[3]; +    XColor xc; + +    if (!ReadFromRFBServer(client, ((char *)&msg) + 1, +			   sz_rfbSetColourMapEntriesMsg - 1)) +      return FALSE; + +    msg.scme.firstColour = rfbClientSwap16IfLE(msg.scme.firstColour); +    msg.scme.nColours = rfbClientSwap16IfLE(msg.scme.nColours); + +    for (i = 0; i < msg.scme.nColours; i++) { +      if (!ReadFromRFBServer(client, (char *)rgb, 6)) +	return FALSE; +      xc.pixel = msg.scme.firstColour + i; +      xc.red = rfbClientSwap16IfLE(rgb[0]); +      xc.green = rfbClientSwap16IfLE(rgb[1]); +      xc.blue = rfbClientSwap16IfLE(rgb[2]); +      xc.flags = DoRed|DoGreen|DoBlue; +      XStoreColor(dpy, cmap, &xc); +    } +    */ + +    break; +  } + +  case rfbFramebufferUpdate: +  { +    rfbFramebufferUpdateRectHeader rect; +    int linesToRead; +    int bytesPerLine; +    int i; + +    if (!ReadFromRFBServer(client, ((char *)&msg.fu) + 1, +			   sz_rfbFramebufferUpdateMsg - 1)) +      return FALSE; + +    msg.fu.nRects = rfbClientSwap16IfLE(msg.fu.nRects); + +    for (i = 0; i < msg.fu.nRects; i++) { +      if (!ReadFromRFBServer(client, (char *)&rect, sz_rfbFramebufferUpdateRectHeader)) +	return FALSE; + +      rect.encoding = rfbClientSwap32IfLE(rect.encoding); +      if (rect.encoding == rfbEncodingLastRect) +	break; + +      rect.r.x = rfbClientSwap16IfLE(rect.r.x); +      rect.r.y = rfbClientSwap16IfLE(rect.r.y); +      rect.r.w = rfbClientSwap16IfLE(rect.r.w); +      rect.r.h = rfbClientSwap16IfLE(rect.r.h); + + +      if (rect.encoding == rfbEncodingXCursor || +	  rect.encoding == rfbEncodingRichCursor) { + +	if (!HandleCursorShape(client, +			       rect.r.x, rect.r.y, rect.r.w, rect.r.h, +			       rect.encoding)) { +	  return FALSE; +	} +	continue; +      } + +      if (rect.encoding == rfbEncodingPointerPos) { +	if (!client->HandleCursorPos(client,rect.r.x, rect.r.y)) { +	  return FALSE; +	} +	continue; +      } +       +      if (rect.encoding == rfbEncodingKeyboardLedState) { +          /* OK! We have received a keyboard state message!!! */ +          client->KeyboardLedStateEnabled = 1; +          if (client->HandleKeyboardLedState!=NULL) +              client->HandleKeyboardLedState(client, rect.r.x, 0); +          /* stash it for the future */ +          client->CurrentKeyboardLedState = rect.r.x; +          continue; +      } + +      if (rect.encoding == rfbEncodingNewFBSize) { +	client->width = rect.r.w; +	client->height = rect.r.h; +	client->updateRect.x = client->updateRect.y = 0; +	client->updateRect.w = client->width; +	client->updateRect.h = client->height; +	client->MallocFrameBuffer(client); +	SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, rect.r.h, FALSE); +	rfbClientLog("Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h); +	continue; +      } + +      /* rect.r.w=byte count */ +      if (rect.encoding == rfbEncodingSupportedMessages) { +          int loop; +          if (!ReadFromRFBServer(client, (char *)&client->supportedMessages, sz_rfbSupportedMessages)) +              return FALSE; + +          /* msgs is two sets of bit flags of supported messages client2server[] and server2client[] */ +          /* currently ignored by this library */ + +          rfbClientLog("client2server supported messages (bit flags)\n"); +          for (loop=0;loop<32;loop+=8) +            rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop, +                client->supportedMessages.client2server[loop],   client->supportedMessages.client2server[loop+1], +                client->supportedMessages.client2server[loop+2], client->supportedMessages.client2server[loop+3], +                client->supportedMessages.client2server[loop+4], client->supportedMessages.client2server[loop+5], +                client->supportedMessages.client2server[loop+6], client->supportedMessages.client2server[loop+7]); + +          rfbClientLog("server2client supported messages (bit flags)\n"); +          for (loop=0;loop<32;loop+=8) +            rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop, +                client->supportedMessages.server2client[loop],   client->supportedMessages.server2client[loop+1], +                client->supportedMessages.server2client[loop+2], client->supportedMessages.server2client[loop+3], +                client->supportedMessages.server2client[loop+4], client->supportedMessages.server2client[loop+5], +                client->supportedMessages.server2client[loop+6], client->supportedMessages.server2client[loop+7]); +          continue; +      } + +      /* rect.r.w=byte count, rect.r.h=# of encodings */ +      if (rect.encoding == rfbEncodingSupportedEncodings) { +          char *buffer; +          buffer = malloc(rect.r.w); +          if (!ReadFromRFBServer(client, buffer, rect.r.w)) +          { +              free(buffer); +              return FALSE; +          } + +          /* buffer now contains rect.r.h # of uint32_t encodings that the server supports */ +          /* currently ignored by this library */ +          free(buffer); +          continue; +      } + +      /* rect.r.w=byte count */ +      if (rect.encoding == rfbEncodingServerIdentity) { +          char *buffer; +          buffer = malloc(rect.r.w+1); +          if (!ReadFromRFBServer(client, buffer, rect.r.w)) +          { +              free(buffer); +              return FALSE; +          } +          buffer[rect.r.w]=0; /* null terminate, just in case */ +          rfbClientLog("Connected to Server \"%s\"\n", buffer); +          free(buffer); +          continue; +      } + +      /* rfbEncodingUltraZip is a collection of subrects.   x = # of subrects, and h is always 0 */ +      if (rect.encoding != rfbEncodingUltraZip) +      { +        if ((rect.r.x + rect.r.w > client->width) || +	    (rect.r.y + rect.r.h > client->height)) +	    { +	      rfbClientLog("Rect too large: %dx%d at (%d, %d)\n", +	  	  rect.r.w, rect.r.h, rect.r.x, rect.r.y); +	      return FALSE; +            } + +        /* UltraVNC with scaling, will send rectangles with a zero W or H +         * +        if ((rect.encoding != rfbEncodingTight) &&  +            (rect.r.h * rect.r.w == 0)) +        { +	  rfbClientLog("Zero size rect - ignoring (encoding=%d (0x%08x) %dx, %dy, %dw, %dh)\n", rect.encoding, rect.encoding, rect.r.x, rect.r.y, rect.r.w, rect.r.h); +	  continue; +        } +        */ +         +        /* If RichCursor encoding is used, we should prevent collisions +	   between framebuffer updates and cursor drawing operations. */ +        client->SoftCursorLockArea(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h); +      } + +      switch (rect.encoding) { + +      case rfbEncodingRaw: { +	int y=rect.r.y, h=rect.r.h; + +	bytesPerLine = rect.r.w * client->format.bitsPerPixel / 8; +	linesToRead = RFB_BUFFER_SIZE / bytesPerLine; + +	while (h > 0) { +	  if (linesToRead > h) +	    linesToRead = h; + +	  if (!ReadFromRFBServer(client, client->buffer,bytesPerLine * linesToRead)) +	    return FALSE; + +	  CopyRectangle(client, (uint8_t *)client->buffer, +			   rect.r.x, y, rect.r.w,linesToRead); + +	  h -= linesToRead; +	  y += linesToRead; + +	} +      } break; + +      case rfbEncodingCopyRect: +      { +	rfbCopyRect cr; + +	if (!ReadFromRFBServer(client, (char *)&cr, sz_rfbCopyRect)) +	  return FALSE; + +	cr.srcX = rfbClientSwap16IfLE(cr.srcX); +	cr.srcY = rfbClientSwap16IfLE(cr.srcY); + +	/* If RichCursor encoding is used, we should extend our +	   "cursor lock area" (previously set to destination +	   rectangle) to the source rectangle as well. */ +	client->SoftCursorLockArea(client, +				   cr.srcX, cr.srcY, rect.r.w, rect.r.h); + +        if (client->GotCopyRect != NULL) { +          client->GotCopyRect(client, cr.srcX, cr.srcY, rect.r.w, rect.r.h, +              rect.r.x, rect.r.y); +        } else +		CopyRectangleFromRectangle(client, +				   cr.srcX, cr.srcY, rect.r.w, rect.r.h, +				   rect.r.x, rect.r.y); + +	break; +      } + +      case rfbEncodingRRE: +      { +	switch (client->format.bitsPerPixel) { +	case 8: +	  if (!HandleRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 16: +	  if (!HandleRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 32: +	  if (!HandleRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	} +	break; +      } + +      case rfbEncodingCoRRE: +      { +	switch (client->format.bitsPerPixel) { +	case 8: +	  if (!HandleCoRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 16: +	  if (!HandleCoRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 32: +	  if (!HandleCoRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	} +	break; +      } + +      case rfbEncodingHextile: +      { +	switch (client->format.bitsPerPixel) { +	case 8: +	  if (!HandleHextile8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 16: +	  if (!HandleHextile16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 32: +	  if (!HandleHextile32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	} +	break; +      } + +      case rfbEncodingUltra: +      { +        switch (client->format.bitsPerPixel) { +        case 8: +          if (!HandleUltra8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +            return FALSE; +          break; +        case 16: +          if (!HandleUltra16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +            return FALSE; +          break; +        case 32: +          if (!HandleUltra32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +            return FALSE; +          break; +        } +        break; +      } +      case rfbEncodingUltraZip: +      { +        switch (client->format.bitsPerPixel) { +        case 8: +          if (!HandleUltraZip8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +            return FALSE; +          break; +        case 16: +          if (!HandleUltraZip16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +            return FALSE; +          break; +        case 32: +          if (!HandleUltraZip32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +            return FALSE; +          break; +        } +        break; +      } + +#ifdef LIBVNCSERVER_HAVE_LIBZ +      case rfbEncodingZlib: +      { +	switch (client->format.bitsPerPixel) { +	case 8: +	  if (!HandleZlib8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 16: +	  if (!HandleZlib16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 32: +	  if (!HandleZlib32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	} +	break; +     } + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +      case rfbEncodingTight: +      { +	switch (client->format.bitsPerPixel) { +	case 8: +	  if (!HandleTight8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 16: +	  if (!HandleTight16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 32: +	  if (!HandleTight32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	} +	break; +      } +#endif +      case rfbEncodingZRLE: +	/* Fail safe for ZYWRLE unsupport VNC server. */ +	client->appData.qualityLevel = 9; +	/* fall through */ +      case rfbEncodingZYWRLE: +      { +	switch (client->format.bitsPerPixel) { +	case 8: +	  if (!HandleZRLE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	case 16: +	  if (client->si.format.greenMax > 0x1F) { +	    if (!HandleZRLE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	      return FALSE; +	  } else { +	    if (!HandleZRLE15(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	      return FALSE; +	  } +	  break; +	case 32: +	{ +	  uint32_t maxColor=(client->format.redMax<<client->format.redShift)| +		(client->format.greenMax<<client->format.greenShift)| +		(client->format.blueMax<<client->format.blueShift); +	  if ((client->format.bigEndian && (maxColor&0xff)==0) || +	      (!client->format.bigEndian && (maxColor&0xff000000)==0)) { +	    if (!HandleZRLE24(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	      return FALSE; +	  } else if (!client->format.bigEndian && (maxColor&0xff)==0) { +	    if (!HandleZRLE24Up(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	      return FALSE; +	  } else if (client->format.bigEndian && (maxColor&0xff000000)==0) { +	    if (!HandleZRLE24Down(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	      return FALSE; +	  } else if (!HandleZRLE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) +	    return FALSE; +	  break; +	} +	} +	break; +     } + +#endif + +      default: +	 { +	   rfbBool handled = FALSE; +	   rfbClientProtocolExtension* e; + +	   for(e = rfbClientExtensions; !handled && e; e = e->next) +	     if(e->handleEncoding && e->handleEncoding(client, &rect)) +	       handled = TRUE; + +	   if(!handled) { +	     rfbClientLog("Unknown rect encoding %d\n", +		 (int)rect.encoding); +	     return FALSE; +	   } +	 } +      } + +      /* Now we may discard "soft cursor locks". */ +      client->SoftCursorUnlockScreen(client); + +      client->GotFrameBufferUpdate(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h); +    } + +    if (!SendIncrementalFramebufferUpdateRequest(client)) +      return FALSE; + +    if (client->FinishedFrameBufferUpdate) +      client->FinishedFrameBufferUpdate(client); + +    break; +  } + +  case rfbBell: +  { +    client->Bell(client); + +    break; +  } + +  case rfbServerCutText: +  { +    char *buffer; + +    if (!ReadFromRFBServer(client, ((char *)&msg) + 1, +			   sz_rfbServerCutTextMsg - 1)) +      return FALSE; + +    msg.sct.length = rfbClientSwap32IfLE(msg.sct.length); + +    buffer = malloc(msg.sct.length+1); + +    if (!ReadFromRFBServer(client, buffer, msg.sct.length)) +      return FALSE; + +    buffer[msg.sct.length] = 0; + +    if (client->GotXCutText) +      client->GotXCutText(client, buffer, msg.sct.length); + +    free(buffer); + +    break; +  } + +  case rfbTextChat: +  { +      char *buffer=NULL; +      if (!ReadFromRFBServer(client, ((char *)&msg) + 1, +                             sz_rfbTextChatMsg- 1)) +        return FALSE; +      msg.tc.length = rfbClientSwap32IfLE(msg.sct.length); +      switch(msg.tc.length) { +      case rfbTextChatOpen: +          rfbClientLog("Received TextChat Open\n"); +          if (client->HandleTextChat!=NULL) +              client->HandleTextChat(client, (int)rfbTextChatOpen, NULL); +          break; +      case rfbTextChatClose: +          rfbClientLog("Received TextChat Close\n"); +         if (client->HandleTextChat!=NULL) +              client->HandleTextChat(client, (int)rfbTextChatClose, NULL); +          break; +      case rfbTextChatFinished: +          rfbClientLog("Received TextChat Finished\n"); +         if (client->HandleTextChat!=NULL) +              client->HandleTextChat(client, (int)rfbTextChatFinished, NULL); +          break; +      default: +          buffer=malloc(msg.tc.length+1); +          if (!ReadFromRFBServer(client, buffer, msg.tc.length)) +          { +              free(buffer); +              return FALSE; +          } +          /* Null Terminate <just in case> */ +          buffer[msg.tc.length]=0; +          rfbClientLog("Received TextChat \"%s\"\n", buffer); +          if (client->HandleTextChat!=NULL) +              client->HandleTextChat(client, (int)msg.tc.length, buffer); +          free(buffer); +          break; +      } +      break; +  } + +  case rfbResizeFrameBuffer: +  { +    if (!ReadFromRFBServer(client, ((char *)&msg) + 1, +                           sz_rfbResizeFrameBufferMsg -1)) +      return FALSE; +    client->width = rfbClientSwap16IfLE(msg.rsfb.framebufferWidth); +    client->height = rfbClientSwap16IfLE(msg.rsfb.framebufferHeigth); +    client->updateRect.x = client->updateRect.y = 0; +    client->updateRect.w = client->width; +    client->updateRect.h = client->height; +    client->MallocFrameBuffer(client); +    SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE); +    rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height); +    break; +  } + +  case rfbPalmVNCReSizeFrameBuffer: +  { +    if (!ReadFromRFBServer(client, ((char *)&msg) + 1, +                           sz_rfbPalmVNCReSizeFrameBufferMsg -1)) +      return FALSE; +    client->width = rfbClientSwap16IfLE(msg.prsfb.buffer_w); +    client->height = rfbClientSwap16IfLE(msg.prsfb.buffer_h); +    client->updateRect.x = client->updateRect.y = 0; +    client->updateRect.w = client->width; +    client->updateRect.h = client->height; +    client->MallocFrameBuffer(client); +    SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE); +    rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height); +    break; +  } + +  default: +    { +      rfbBool handled = FALSE; +      rfbClientProtocolExtension* e; + +      for(e = rfbClientExtensions; !handled && e; e = e->next) +	if(e->handleMessage && e->handleMessage(client, &msg)) +	  handled = TRUE; + +      if(!handled) { +	char buffer[256]; +	rfbClientLog("Unknown message type %d from VNC server\n",msg.type); +	ReadFromRFBServer(client, buffer, 256); +	return FALSE; +      } +    } +  } + +  return TRUE; +} + + +#define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++) + +#define GET_PIXEL16(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \ +			       ((uint8_t*)&(pix))[1] = *(ptr)++) + +#define GET_PIXEL32(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \ +			       ((uint8_t*)&(pix))[1] = *(ptr)++, \ +			       ((uint8_t*)&(pix))[2] = *(ptr)++, \ +			       ((uint8_t*)&(pix))[3] = *(ptr)++) + +/* CONCAT2 concatenates its two arguments.  CONCAT2E does the same but also +   expands its arguments if they are macros */ + +#define CONCAT2(a,b) a##b +#define CONCAT2E(a,b) CONCAT2(a,b) +#define CONCAT3(a,b,c) a##b##c +#define CONCAT3E(a,b,c) CONCAT3(a,b,c) + +#define BPP 8 +#include "rre.c" +#include "corre.c" +#include "hextile.c" +#include "ultra.c" +#include "zlib.c" +#include "tight.c" +#include "zrle.c" +#undef BPP +#define BPP 16 +#include "rre.c" +#include "corre.c" +#include "hextile.c" +#include "ultra.c" +#include "zlib.c" +#include "tight.c" +#include "zrle.c" +#define REALBPP 15 +#include "zrle.c" +#undef BPP +#define BPP 32 +#include "rre.c" +#include "corre.c" +#include "hextile.c" +#include "ultra.c" +#include "zlib.c" +#include "tight.c" +#include "zrle.c" +#define REALBPP 24 +#include "zrle.c" +#define REALBPP 24 +#define UNCOMP 8 +#include "zrle.c" +#define REALBPP 24 +#define UNCOMP -8 +#include "zrle.c" +#undef BPP + + +/* + * PrintPixelFormat. + */ + +void +PrintPixelFormat(rfbPixelFormat *format) +{ +  if (format->bitsPerPixel == 1) { +    rfbClientLog("  Single bit per pixel.\n"); +    rfbClientLog( +	    "  %s significant bit in each byte is leftmost on the screen.\n", +	    (format->bigEndian ? "Most" : "Least")); +  } else { +    rfbClientLog("  %d bits per pixel.\n",format->bitsPerPixel); +    if (format->bitsPerPixel != 8) { +      rfbClientLog("  %s significant byte first in each pixel.\n", +	      (format->bigEndian ? "Most" : "Least")); +    } +    if (format->trueColour) { +      rfbClientLog("  TRUE colour: max red %d green %d blue %d" +		   ", shift red %d green %d blue %d\n", +		   format->redMax, format->greenMax, format->blueMax, +		   format->redShift, format->greenShift, format->blueShift); +    } else { +      rfbClientLog("  Colour map (not true colour).\n"); +    } +  } +} + +/* avoid name clashes with LibVNCServer */ + +#define rfbEncryptBytes rfbClientEncryptBytes +#define rfbEncryptBytes2 rfbClientEncryptBytes2 +#define rfbDes rfbClientDes +#define rfbDesKey rfbClientDesKey +#define rfbUseKey rfbClientUseKey +#define rfbCPKey rfbClientCPKey + +#include "../libvncserver/vncauth.c" +#include "../libvncserver/d3des.c" diff --git a/3rdParty/LibVNC/src/libvncclient/rre.c b/3rdParty/LibVNC/src/libvncclient/rre.c new file mode 100644 index 0000000..94158c9 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/rre.c @@ -0,0 +1,68 @@ +/* + *  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. + */ + +/* + * rre.c - handle RRE 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 an RRE + * encoded rectangle with BPP bits per pixel. + */ + +#define HandleRREBPP CONCAT2E(HandleRRE,BPP) +#define CARDBPP CONCAT3E(uint,BPP,_t) + +static rfbBool +HandleRREBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ +  rfbRREHeader hdr; +  int i; +  CARDBPP pix; +  rfbRectangle subrect; + +  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); + +  for (i = 0; i < hdr.nSubrects; i++) { +    if (!ReadFromRFBServer(client, (char *)&pix, sizeof(pix))) +      return FALSE; + +    if (!ReadFromRFBServer(client, (char *)&subrect, sz_rfbRectangle)) +      return FALSE; + +    subrect.x = rfbClientSwap16IfLE(subrect.x); +    subrect.y = rfbClientSwap16IfLE(subrect.y); +    subrect.w = rfbClientSwap16IfLE(subrect.w); +    subrect.h = rfbClientSwap16IfLE(subrect.h); + +    FillRectangle(client, rx+subrect.x, ry+subrect.y, subrect.w, subrect.h, pix); +  } + +  return TRUE; +} + +#undef CARDBPP diff --git a/3rdParty/LibVNC/src/libvncclient/sockets.c b/3rdParty/LibVNC/src/libvncclient/sockets.c new file mode 100644 index 0000000..598dd39 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/sockets.c @@ -0,0 +1,616 @@ +/* + *  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. + */ + +/* + * sockets.c - functions to deal with sockets. + */ + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#endif +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <assert.h> +#include <rfb/rfbclient.h> +#ifdef WIN32 +#undef SOCKET +#include <winsock2.h> +#define EWOULDBLOCK WSAEWOULDBLOCK +#define close closesocket +#define read(sock,buf,len) recv(sock,buf,len,0) +#define write(sock,buf,len) send(sock,buf,len,0) +#define socklen_t int +#else +#include <sys/socket.h> +#include <netinet/in.h> +#include <sys/un.h> +#include <netinet/tcp.h> +#include <arpa/inet.h> +#include <netdb.h> +#endif +#include "tls.h" + +void PrintInHex(char *buf, int len); + +rfbBool errorMessageOnReadFailure = TRUE; + +/* + * ReadFromRFBServer is called whenever we want to read some data from the RFB + * server.  It is non-trivial for two reasons: + * + * 1. For efficiency it performs some intelligent buffering, avoiding invoking + *    the read() system call too often.  For small chunks of data, it simply + *    copies the data out of an internal buffer.  For large amounts of data it + *    reads directly into the buffer provided by the caller. + * + * 2. Whenever read() would block, it invokes the Xt event dispatching + *    mechanism to process X events.  In fact, this is the only place these + *    events are processed, as there is no XtAppMainLoop in the program. + */ + +rfbBool +ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) +{ +#undef DEBUG_READ_EXACT +#ifdef DEBUG_READ_EXACT +	char* oout=out; +	int nn=n; +	rfbClientLog("ReadFromRFBServer %d bytes\n",n); +#endif +  if (client->serverPort==-1) { +    /* vncrec playing */ +    rfbVNCRec* rec = client->vncRec; +    struct timeval tv; + +    if (rec->readTimestamp) { +      rec->readTimestamp = FALSE; +      if (!fread(&tv,sizeof(struct timeval),1,rec->file)) +        return FALSE; + +      tv.tv_sec = rfbClientSwap32IfLE (tv.tv_sec); +      tv.tv_usec = rfbClientSwap32IfLE (tv.tv_usec); + +      if (rec->tv.tv_sec!=0 && !rec->doNotSleep) { +        struct timeval diff; +        diff.tv_sec = tv.tv_sec - rec->tv.tv_sec; +        diff.tv_usec = tv.tv_usec - rec->tv.tv_usec; +        if(diff.tv_usec<0) { +	  diff.tv_sec--; +	  diff.tv_usec+=1000000; +        } +#ifndef __MINGW32__ +        sleep (diff.tv_sec); +        usleep (diff.tv_usec); +#else +	Sleep (diff.tv_sec * 1000 + diff.tv_usec/1000); +#endif +      } + +      rec->tv=tv; +    } +     +    return (fread(out,1,n,rec->file)<0?FALSE:TRUE); +  } +   +  if (n <= client->buffered) { +    memcpy(out, client->bufoutptr, n); +    client->bufoutptr += n; +    client->buffered -= n; +#ifdef DEBUG_READ_EXACT +    goto hexdump; +#endif +    return TRUE; +  } + +  memcpy(out, client->bufoutptr, client->buffered); + +  out += client->buffered; +  n -= client->buffered; + +  client->bufoutptr = client->buf; +  client->buffered = 0; + +  if (n <= RFB_BUF_SIZE) { + +    while (client->buffered < n) { +      int i; +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +      if (client->tlsSession) { +        i = ReadFromTLS(client, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered); +      } else { +#endif +        i = read(client->sock, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered); +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +      } +#endif +      if (i <= 0) { +	if (i < 0) { +#ifdef WIN32 +	  errno=WSAGetLastError(); +#endif +	  if (errno == EWOULDBLOCK || errno == EAGAIN) { +	    /* TODO: +	       ProcessXtEvents(); +	    */ +	    i = 0; +	  } else { +	    rfbClientErr("read (%d: %s)\n",errno,strerror(errno)); +	    return FALSE; +	  } +	} else { +	  if (errorMessageOnReadFailure) { +	    rfbClientLog("VNC server closed connection\n"); +	  } +	  return FALSE; +	} +      } +      client->buffered += i; +    } + +    memcpy(out, client->bufoutptr, n); +    client->bufoutptr += n; +    client->buffered -= n; + +  } else { + +    while (n > 0) { +      int i; +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +      if (client->tlsSession) { +        i = ReadFromTLS(client, out, n); +      } else { +#endif +        i = read(client->sock, out, n); +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +      } +#endif +      if (i <= 0) { +	if (i < 0) { +#ifdef WIN32 +	  errno=WSAGetLastError(); +#endif +	  if (errno == EWOULDBLOCK || errno == EAGAIN) { +	    /* TODO: +	       ProcessXtEvents(); +	    */ +	    i = 0; +	  } else { +	    rfbClientErr("read (%s)\n",strerror(errno)); +	    return FALSE; +	  } +	} else { +	  if (errorMessageOnReadFailure) { +	    rfbClientLog("VNC server closed connection\n"); +	  } +	  return FALSE; +	} +      } +      out += i; +      n -= i; +    } +  } + +#ifdef DEBUG_READ_EXACT +hexdump: +  { int ii; +    for(ii=0;ii<nn;ii++) +      fprintf(stderr,"%02x ",(unsigned char)oout[ii]); +    fprintf(stderr,"\n"); +  } +#endif + +  return TRUE; +} + + +/* + * Write an exact number of bytes, and don't return until you've sent them. + */ + +rfbBool +WriteToRFBServer(rfbClient* client, char *buf, int n) +{ +  fd_set fds; +  int i = 0; +  int j; + +  if (client->serverPort==-1) +    return TRUE; /* vncrec playing */ + +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +  if (client->tlsSession) { +    /* WriteToTLS() will guarantee either everything is written, or error/eof returns */ +    i = WriteToTLS(client, buf, n); +    if (i <= 0) return FALSE; + +    return TRUE; +  } +#endif + +  while (i < n) { +    j = write(client->sock, buf + i, (n - i)); +    if (j <= 0) { +      if (j < 0) { +	if (errno == EWOULDBLOCK || +#ifdef LIBVNCSERVER_ENOENT_WORKAROUND +		errno == ENOENT || +#endif +		errno == EAGAIN) { +	  FD_ZERO(&fds); +	  FD_SET(client->sock,&fds); + +	  if (select(client->sock+1, NULL, &fds, NULL, NULL) <= 0) { +	    rfbClientErr("select\n"); +	    return FALSE; +	  } +	  j = 0; +	} else { +	  rfbClientErr("write\n"); +	  return FALSE; +	} +      } else { +	rfbClientLog("write failed\n"); +	return FALSE; +      } +    } +    i += j; +  } +  return TRUE; +} + + + +static int initSockets() { +#ifdef WIN32 +  WSADATA trash; +  static rfbBool WSAinitted=FALSE; +  if(!WSAinitted) { +    int i=WSAStartup(MAKEWORD(2,0),&trash); +    if(i!=0) { +      rfbClientErr("Couldn't init Windows Sockets\n"); +      return 0; +    } +    WSAinitted=TRUE; +  } +#endif +  return 1; +} + +/* + * ConnectToTcpAddr connects to the given TCP port. + */ + +int +ConnectClientToTcpAddr(unsigned int host, int port) +{ +  int sock; +  struct sockaddr_in addr; +  int one = 1; + +  if (!initSockets()) +	  return -1; + +  addr.sin_family = AF_INET; +  addr.sin_port = htons(port); +  addr.sin_addr.s_addr = host; + +  sock = socket(AF_INET, SOCK_STREAM, 0); +  if (sock < 0) { +#ifdef WIN32 +    errno=WSAGetLastError(); +#endif +    rfbClientErr("ConnectToTcpAddr: socket (%s)\n",strerror(errno)); +    return -1; +  } + +  if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { +    rfbClientErr("ConnectToTcpAddr: connect\n"); +    close(sock); +    return -1; +  } + +  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, +		 (char *)&one, sizeof(one)) < 0) { +    rfbClientErr("ConnectToTcpAddr: setsockopt\n"); +    close(sock); +    return -1; +  } + +  return sock; +} + +int +ConnectClientToUnixSock(const char *sockFile) +{ +#ifdef WIN32 +  rfbClientErr("Windows doesn't support UNIX sockets\n"); +  return -1; +#else +  int sock; +  struct sockaddr_un addr; +  addr.sun_family = AF_UNIX; +  strcpy(addr.sun_path, sockFile); + +  sock = socket(AF_UNIX, SOCK_STREAM, 0); +  if (sock < 0) { +    rfbClientErr("ConnectToUnixSock: socket (%s)\n",strerror(errno)); +    return -1; +  } + +  if (connect(sock, (struct sockaddr *)&addr, sizeof(addr.sun_family) + strlen(addr.sun_path)) < 0) { +    rfbClientErr("ConnectToUnixSock: connect\n"); +    close(sock); +    return -1; +  } + +  return sock; +#endif +} + + + +/* + * FindFreeTcpPort tries to find unused TCP port in the range + * (TUNNEL_PORT_OFFSET, TUNNEL_PORT_OFFSET + 99]. Returns 0 on failure. + */ + +int +FindFreeTcpPort(void) +{ +  int sock, port; +  struct sockaddr_in addr; + +  addr.sin_family = AF_INET; +  addr.sin_addr.s_addr = htonl(INADDR_ANY); + +  if (!initSockets()) +    return -1; + +  sock = socket(AF_INET, SOCK_STREAM, 0); +  if (sock < 0) { +    rfbClientErr(": FindFreeTcpPort: socket\n"); +    return 0; +  } + +  for (port = TUNNEL_PORT_OFFSET + 99; port > TUNNEL_PORT_OFFSET; port--) { +    addr.sin_port = htons((unsigned short)port); +    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { +      close(sock); +      return port; +    } +  } + +  close(sock); +  return 0; +} + + +/* + * ListenAtTcpPort starts listening at the given TCP port. + */ + +int +ListenAtTcpPort(int port) +{ +  int sock; +  struct sockaddr_in addr; +  int one = 1; + +  addr.sin_family = AF_INET; +  addr.sin_port = htons(port); +  addr.sin_addr.s_addr = htonl(INADDR_ANY); + +  if (!initSockets()) +    return -1; + +  sock = socket(AF_INET, SOCK_STREAM, 0); +  if (sock < 0) { +    rfbClientErr("ListenAtTcpPort: socket\n"); +    return -1; +  } + +  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, +		 (const char *)&one, sizeof(one)) < 0) { +    rfbClientErr("ListenAtTcpPort: setsockopt\n"); +    close(sock); +    return -1; +  } + +  if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { +    rfbClientErr("ListenAtTcpPort: bind\n"); +    close(sock); +    return -1; +  } + +  if (listen(sock, 5) < 0) { +    rfbClientErr("ListenAtTcpPort: listen\n"); +    close(sock); +    return -1; +  } + +  return sock; +} + + +/* + * AcceptTcpConnection accepts a TCP connection. + */ + +int +AcceptTcpConnection(int listenSock) +{ +  int sock; +  struct sockaddr_in addr; +  socklen_t addrlen = sizeof(addr); +  int one = 1; + +  sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen); +  if (sock < 0) { +    rfbClientErr("AcceptTcpConnection: accept\n"); +    return -1; +  } + +  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, +		 (char *)&one, sizeof(one)) < 0) { +    rfbClientErr("AcceptTcpConnection: setsockopt\n"); +    close(sock); +    return -1; +  } + +  return sock; +} + + +/* + * SetNonBlocking sets a socket into non-blocking mode. + */ + +rfbBool +SetNonBlocking(int sock) +{ +#ifndef __MINGW32__ +  if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { +    rfbClientErr("AcceptTcpConnection: fcntl\n"); +    return FALSE; +  } +#else +  rfbClientErr("O_NONBLOCK on MinGW32 NOT IMPLEMENTED\n"); +#endif +  return TRUE; +} + + +/* + * StringToIPAddr - convert a host string to an IP address. + */ + +rfbBool +StringToIPAddr(const char *str, unsigned int *addr) +{ +  struct hostent *hp; + +  if (strcmp(str,"") == 0) { +    *addr = htonl(INADDR_LOOPBACK); /* local */ +    return TRUE; +  } + +  *addr = inet_addr(str); + +  if (*addr != -1) +    return TRUE; + +  if (!initSockets()) +	  return -1; + +  hp = gethostbyname(str); + +  if (hp) { +    *addr = *(unsigned int *)hp->h_addr; +    return TRUE; +  } + +  return FALSE; +} + + +/* + * Test if the other end of a socket is on the same machine. + */ + +rfbBool +SameMachine(int sock) +{ +  struct sockaddr_in peeraddr, myaddr; +  socklen_t addrlen = sizeof(struct sockaddr_in); + +  getpeername(sock, (struct sockaddr *)&peeraddr, &addrlen); +  getsockname(sock, (struct sockaddr *)&myaddr, &addrlen); + +  return (peeraddr.sin_addr.s_addr == myaddr.sin_addr.s_addr); +} + + +/* + * Print out the contents of a packet for debugging. + */ + +void +PrintInHex(char *buf, int len) +{ +  int i, j; +  char c, str[17]; + +  str[16] = 0; + +  rfbClientLog("ReadExact: "); + +  for (i = 0; i < len; i++) +    { +      if ((i % 16 == 0) && (i != 0)) { +	rfbClientLog("           "); +      } +      c = buf[i]; +      str[i % 16] = (((c > 31) && (c < 127)) ? c : '.'); +      rfbClientLog("%02x ",(unsigned char)c); +      if ((i % 4) == 3) +	rfbClientLog(" "); +      if ((i % 16) == 15) +	{ +	  rfbClientLog("%s\n",str); +	} +    } +  if ((i % 16) != 0) +    { +      for (j = i % 16; j < 16; j++) +	{ +	  rfbClientLog("   "); +	  if ((j % 4) == 3) rfbClientLog(" "); +	} +      str[i % 16] = 0; +      rfbClientLog("%s\n",str); +    } + +  fflush(stderr); +} + +int WaitForMessage(rfbClient* client,unsigned int usecs) +{ +  fd_set fds; +  struct timeval timeout; +  int num; + +  if (client->serverPort==-1) +    /* playing back vncrec file */ +    return 1; +   +  timeout.tv_sec=(usecs/1000000); +  timeout.tv_usec=(usecs%1000000); + +  FD_ZERO(&fds); +  FD_SET(client->sock,&fds); + +  num=select(client->sock+1, &fds, NULL, NULL, &timeout); +  if(num<0) +    rfbClientLog("Waiting for message failed: %d (%s)\n",errno,strerror(errno)); + +  return num; +} + + diff --git a/3rdParty/LibVNC/src/libvncclient/tight.c b/3rdParty/LibVNC/src/libvncclient/tight.c new file mode 100644 index 0000000..2f9fbab --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/tight.c @@ -0,0 +1,688 @@ +/* + *  Copyright (C) 2000, 2001 Const Kaplinsky.  All Rights Reserved. + * + *  This is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This software is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this software; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, + *  USA. + */ + +#ifdef LIBVNCSERVER_HAVE_LIBZ +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + +/* + * tight.c - handle ``tight'' 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 tight-encoded rectangle with BPP bits per pixel. + * + */ + +#define TIGHT_MIN_TO_COMPRESS 12 + +#define CARDBPP CONCAT3E(uint,BPP,_t) +#define filterPtrBPP CONCAT2E(filterPtr,BPP) + +#define HandleTightBPP CONCAT2E(HandleTight,BPP) +#define InitFilterCopyBPP CONCAT2E(InitFilterCopy,BPP) +#define InitFilterPaletteBPP CONCAT2E(InitFilterPalette,BPP) +#define InitFilterGradientBPP CONCAT2E(InitFilterGradient,BPP) +#define FilterCopyBPP CONCAT2E(FilterCopy,BPP) +#define FilterPaletteBPP CONCAT2E(FilterPalette,BPP) +#define FilterGradientBPP CONCAT2E(FilterGradient,BPP) + +#if BPP != 8 +#define DecompressJpegRectBPP CONCAT2E(DecompressJpegRect,BPP) +#endif + +#ifndef RGB_TO_PIXEL + +#define RGB_TO_PIXEL(bpp,r,g,b)						\ +  (((CARD##bpp)(r) & client->format.redMax) << client->format.redShift |		\ +   ((CARD##bpp)(g) & client->format.greenMax) << client->format.greenShift |	\ +   ((CARD##bpp)(b) & client->format.blueMax) << client->format.blueShift) + +#define RGB24_TO_PIXEL(bpp,r,g,b)                                       \ +   ((((CARD##bpp)(r) & 0xFF) * client->format.redMax + 127) / 255             \ +    << client->format.redShift |                                              \ +    (((CARD##bpp)(g) & 0xFF) * client->format.greenMax + 127) / 255           \ +    << client->format.greenShift |                                            \ +    (((CARD##bpp)(b) & 0xFF) * client->format.blueMax + 127) / 255            \ +    << client->format.blueShift) + +#define RGB24_TO_PIXEL32(r,g,b)						\ +  (((uint32_t)(r) & 0xFF) << client->format.redShift |				\ +   ((uint32_t)(g) & 0xFF) << client->format.greenShift |			\ +   ((uint32_t)(b) & 0xFF) << client->format.blueShift) + +#endif + +/* Type declarations */ + +typedef void (*filterPtrBPP)(rfbClient* client, int, CARDBPP *); + +/* Prototypes */ + +static int InitFilterCopyBPP (rfbClient* client, int rw, int rh); +static int InitFilterPaletteBPP (rfbClient* client, int rw, int rh); +static int InitFilterGradientBPP (rfbClient* client, int rw, int rh); +static void FilterCopyBPP (rfbClient* client, int numRows, CARDBPP *destBuffer); +static void FilterPaletteBPP (rfbClient* client, int numRows, CARDBPP *destBuffer); +static void FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *destBuffer); + +#if BPP != 8 +static rfbBool DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h); +#endif + +/* Definitions */ + +static rfbBool +HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ +  CARDBPP fill_colour; +  uint8_t comp_ctl; +  uint8_t filter_id; +  filterPtrBPP filterFn; +  z_streamp zs; +  char *buffer2; +  int err, stream_id, compressedLen, bitsPixel; +  int bufferSize, rowSize, numRows, portionLen, rowsProcessed, extraBytes; + +  if (!ReadFromRFBServer(client, (char *)&comp_ctl, 1)) +    return FALSE; + +  /* Flush zlib streams if we are told by the server to do so. */ +  for (stream_id = 0; stream_id < 4; stream_id++) { +    if ((comp_ctl & 1) && client->zlibStreamActive[stream_id]) { +      if (inflateEnd (&client->zlibStream[stream_id]) != Z_OK && +	  client->zlibStream[stream_id].msg != NULL) +	rfbClientLog("inflateEnd: %s\n", client->zlibStream[stream_id].msg); +      client->zlibStreamActive[stream_id] = FALSE; +    } +    comp_ctl >>= 1; +  } + +  /* Handle solid rectangles. */ +  if (comp_ctl == rfbTightFill) { +#if BPP == 32 +    if (client->format.depth == 24 && client->format.redMax == 0xFF && +	client->format.greenMax == 0xFF && client->format.blueMax == 0xFF) { +      if (!ReadFromRFBServer(client, client->buffer, 3)) +	return FALSE; +      fill_colour = RGB24_TO_PIXEL32(client->buffer[0], client->buffer[1], client->buffer[2]); +    } else { +      if (!ReadFromRFBServer(client, (char*)&fill_colour, sizeof(fill_colour))) +	return FALSE; +    } +#else +    if (!ReadFromRFBServer(client, (char*)&fill_colour, sizeof(fill_colour))) +	return FALSE; +#endif + +    FillRectangle(client, rx, ry, rw, rh, fill_colour); + +    return TRUE; +  } + +#if BPP == 8 +  if (comp_ctl == rfbTightJpeg) { +    rfbClientLog("Tight encoding: JPEG is not supported in 8 bpp mode.\n"); +    return FALSE; +  } +#else +  if (comp_ctl == rfbTightJpeg) { +    return DecompressJpegRectBPP(client, rx, ry, rw, rh); +  } +#endif + +  /* Quit on unsupported subencoding value. */ +  if (comp_ctl > rfbTightMaxSubencoding) { +    rfbClientLog("Tight encoding: bad subencoding value received.\n"); +    return FALSE; +  } + +  /* +   * Here primary compression mode handling begins. +   * Data was processed with optional filter + zlib compression. +   */ + +  /* First, we should identify a filter to use. */ +  if ((comp_ctl & rfbTightExplicitFilter) != 0) { +    if (!ReadFromRFBServer(client, (char*)&filter_id, 1)) +      return FALSE; + +    switch (filter_id) { +    case rfbTightFilterCopy: +      filterFn = FilterCopyBPP; +      bitsPixel = InitFilterCopyBPP(client, rw, rh); +      break; +    case rfbTightFilterPalette: +      filterFn = FilterPaletteBPP; +      bitsPixel = InitFilterPaletteBPP(client, rw, rh); +      break; +    case rfbTightFilterGradient: +      filterFn = FilterGradientBPP; +      bitsPixel = InitFilterGradientBPP(client, rw, rh); +      break; +    default: +      rfbClientLog("Tight encoding: unknown filter code received.\n"); +      return FALSE; +    } +  } else { +    filterFn = FilterCopyBPP; +    bitsPixel = InitFilterCopyBPP(client, rw, rh); +  } +  if (bitsPixel == 0) { +    rfbClientLog("Tight encoding: error receiving palette.\n"); +    return FALSE; +  } + +  /* Determine if the data should be decompressed or just copied. */ +  rowSize = (rw * bitsPixel + 7) / 8; +  if (rh * rowSize < TIGHT_MIN_TO_COMPRESS) { +    if (!ReadFromRFBServer(client, (char*)client->buffer, rh * rowSize)) +      return FALSE; + +    buffer2 = &client->buffer[TIGHT_MIN_TO_COMPRESS * 4]; +    filterFn(client, rh, (CARDBPP *)buffer2); + +    CopyRectangle(client, (uint8_t *)buffer2, rx, ry, rw, rh); + +    return TRUE; +  } + +  /* Read the length (1..3 bytes) of compressed data following. */ +  compressedLen = (int)ReadCompactLen(client); +  if (compressedLen <= 0) { +    rfbClientLog("Incorrect data received from the server.\n"); +    return FALSE; +  } + +  /* Now let's initialize compression stream if needed. */ +  stream_id = comp_ctl & 0x03; +  zs = &client->zlibStream[stream_id]; +  if (!client->zlibStreamActive[stream_id]) { +    zs->zalloc = Z_NULL; +    zs->zfree = Z_NULL; +    zs->opaque = Z_NULL; +    err = inflateInit(zs); +    if (err != Z_OK) { +      if (zs->msg != NULL) +	rfbClientLog("InflateInit error: %s.\n", zs->msg); +      return FALSE; +    } +    client->zlibStreamActive[stream_id] = TRUE; +  } + +  /* Read, decode and draw actual pixel data in a loop. */ + +  bufferSize = RFB_BUFFER_SIZE * bitsPixel / (bitsPixel + BPP) & 0xFFFFFFFC; +  buffer2 = &client->buffer[bufferSize]; +  if (rowSize > bufferSize) { +    /* Should be impossible when RFB_BUFFER_SIZE >= 16384 */ +    rfbClientLog("Internal error: incorrect buffer size.\n"); +    return FALSE; +  } + +  rowsProcessed = 0; +  extraBytes = 0; + +  while (compressedLen > 0) { +    if (compressedLen > ZLIB_BUFFER_SIZE) +      portionLen = ZLIB_BUFFER_SIZE; +    else +      portionLen = compressedLen; + +    if (!ReadFromRFBServer(client, (char*)client->zlib_buffer, portionLen)) +      return FALSE; + +    compressedLen -= portionLen; + +    zs->next_in = (Bytef *)client->zlib_buffer; +    zs->avail_in = portionLen; + +    do { +      zs->next_out = (Bytef *)&client->buffer[extraBytes]; +      zs->avail_out = bufferSize - extraBytes; + +      err = inflate(zs, Z_SYNC_FLUSH); +      if (err == Z_BUF_ERROR)   /* Input exhausted -- no problem. */ +	break; +      if (err != Z_OK && err != Z_STREAM_END) { +	if (zs->msg != NULL) { +	  rfbClientLog("Inflate error: %s.\n", zs->msg); +	} else { +	  rfbClientLog("Inflate error: %d.\n", err); +	} +	return FALSE; +      } + +      numRows = (bufferSize - zs->avail_out) / rowSize; + +      filterFn(client, numRows, (CARDBPP *)buffer2); + +      extraBytes = bufferSize - zs->avail_out - numRows * rowSize; +      if (extraBytes > 0) +	memcpy(client->buffer, &client->buffer[numRows * rowSize], extraBytes); + +      CopyRectangle(client, (uint8_t *)buffer2, rx, ry+rowsProcessed, rw, numRows); + +      rowsProcessed += numRows; +    } +    while (zs->avail_out == 0); +  } + +  if (rowsProcessed != rh) { +    rfbClientLog("Incorrect number of scan lines after decompression.\n"); +    return FALSE; +  } + +  return TRUE; +} + +/*---------------------------------------------------------------------------- + * + * Filter stuff. + * + */ + +static int +InitFilterCopyBPP (rfbClient* client, int rw, int rh) +{ +  client->rectWidth = rw; + +#if BPP == 32 +  if (client->format.depth == 24 && client->format.redMax == 0xFF && +      client->format.greenMax == 0xFF && client->format.blueMax == 0xFF) { +    client->cutZeros = TRUE; +    return 24; +  } else { +    client->cutZeros = FALSE; +  } +#endif + +  return BPP; +} + +static void +FilterCopyBPP (rfbClient* client, int numRows, CARDBPP *dst) +{ + +#if BPP == 32 +  int x, y; + +  if (client->cutZeros) { +    for (y = 0; y < numRows; y++) { +      for (x = 0; x < client->rectWidth; x++) { +	dst[y*client->rectWidth+x] = +	  RGB24_TO_PIXEL32(client->buffer[(y*client->rectWidth+x)*3], +			   client->buffer[(y*client->rectWidth+x)*3+1], +			   client->buffer[(y*client->rectWidth+x)*3+2]); +      } +    } +    return; +  } +#endif + +  memcpy (dst, client->buffer, numRows * client->rectWidth * (BPP / 8)); +} + +static int +InitFilterGradientBPP (rfbClient* client, int rw, int rh) +{ +  int bits; + +  bits = InitFilterCopyBPP(client, rw, rh); +  if (client->cutZeros) +    memset(client->tightPrevRow, 0, rw * 3); +  else +    memset(client->tightPrevRow, 0, rw * 3 * sizeof(uint16_t)); + +  return bits; +} + +#if BPP == 32 + +static void +FilterGradient24 (rfbClient* client, int numRows, uint32_t *dst) +{ +  int x, y, c; +  uint8_t thisRow[2048*3]; +  uint8_t pix[3]; +  int est[3]; + +  for (y = 0; y < numRows; y++) { + +    /* First pixel in a row */ +    for (c = 0; c < 3; c++) { +      pix[c] = client->tightPrevRow[c] + client->buffer[y*client->rectWidth*3+c]; +      thisRow[c] = pix[c]; +    } +    dst[y*client->rectWidth] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); + +    /* Remaining pixels of a row */ +    for (x = 1; x < client->rectWidth; x++) { +      for (c = 0; c < 3; c++) { +	est[c] = (int)client->tightPrevRow[x*3+c] + (int)pix[c] - +		 (int)client->tightPrevRow[(x-1)*3+c]; +	if (est[c] > 0xFF) { +	  est[c] = 0xFF; +	} else if (est[c] < 0x00) { +	  est[c] = 0x00; +	} +	pix[c] = (uint8_t)est[c] + client->buffer[(y*client->rectWidth+x)*3+c]; +	thisRow[x*3+c] = pix[c]; +      } +      dst[y*client->rectWidth+x] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); +    } + +    memcpy(client->tightPrevRow, thisRow, client->rectWidth * 3); +  } +} + +#endif + +static void +FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst) +{ +  int x, y, c; +  CARDBPP *src = (CARDBPP *)client->buffer; +  uint16_t *thatRow = (uint16_t *)client->tightPrevRow; +  uint16_t thisRow[2048*3]; +  uint16_t pix[3]; +  uint16_t max[3]; +  int shift[3]; +  int est[3]; + +#if BPP == 32 +  if (client->cutZeros) { +    FilterGradient24(client, numRows, dst); +    return; +  } +#endif + +  max[0] = client->format.redMax; +  max[1] = client->format.greenMax; +  max[2] = client->format.blueMax; + +  shift[0] = client->format.redShift; +  shift[1] = client->format.greenShift; +  shift[2] = client->format.blueShift; + +  for (y = 0; y < numRows; y++) { + +    /* First pixel in a row */ +    for (c = 0; c < 3; c++) { +      pix[c] = (uint16_t)(((src[y*client->rectWidth] >> shift[c]) + thatRow[c]) & max[c]); +      thisRow[c] = pix[c]; +    } +    dst[y*client->rectWidth] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); + +    /* Remaining pixels of a row */ +    for (x = 1; x < client->rectWidth; x++) { +      for (c = 0; c < 3; c++) { +	est[c] = (int)thatRow[x*3+c] + (int)pix[c] - (int)thatRow[(x-1)*3+c]; +	if (est[c] > (int)max[c]) { +	  est[c] = (int)max[c]; +	} else if (est[c] < 0) { +	  est[c] = 0; +	} +	pix[c] = (uint16_t)(((src[y*client->rectWidth+x] >> shift[c]) + est[c]) & max[c]); +	thisRow[x*3+c] = pix[c]; +      } +      dst[y*client->rectWidth+x] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); +    } +    memcpy(thatRow, thisRow, client->rectWidth * 3 * sizeof(uint16_t)); +  } +} + +static int +InitFilterPaletteBPP (rfbClient* client, int rw, int rh) +{ +  uint8_t numColors; +#if BPP == 32 +  int i; +  CARDBPP *palette = (CARDBPP *)client->tightPalette; +#endif + +  client->rectWidth = rw; + +  if (!ReadFromRFBServer(client, (char*)&numColors, 1)) +    return 0; + +  client->rectColors = (int)numColors; +  if (++client->rectColors < 2) +    return 0; + +#if BPP == 32 +  if (client->format.depth == 24 && client->format.redMax == 0xFF && +      client->format.greenMax == 0xFF && client->format.blueMax == 0xFF) { +    if (!ReadFromRFBServer(client, (char*)&client->tightPalette, client->rectColors * 3)) +      return 0; +    for (i = client->rectColors - 1; i >= 0; i--) { +      palette[i] = RGB24_TO_PIXEL32(client->tightPalette[i*3], +				    client->tightPalette[i*3+1], +				    client->tightPalette[i*3+2]); +    } +    return (client->rectColors == 2) ? 1 : 8; +  } +#endif + +  if (!ReadFromRFBServer(client, (char*)&client->tightPalette, client->rectColors * (BPP / 8))) +    return 0; + +  return (client->rectColors == 2) ? 1 : 8; +} + +static void +FilterPaletteBPP (rfbClient* client, int numRows, CARDBPP *dst) +{ +  int x, y, b, w; +  uint8_t *src = (uint8_t *)client->buffer; +  CARDBPP *palette = (CARDBPP *)client->tightPalette; + +  if (client->rectColors == 2) { +    w = (client->rectWidth + 7) / 8; +    for (y = 0; y < numRows; y++) { +      for (x = 0; x < client->rectWidth / 8; x++) { +	for (b = 7; b >= 0; b--) +	  dst[y*client->rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1]; +      } +      for (b = 7; b >= 8 - client->rectWidth % 8; b--) { +	dst[y*client->rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1]; +      } +    } +  } else { +    for (y = 0; y < numRows; y++) +      for (x = 0; x < client->rectWidth; x++) +	dst[y*client->rectWidth+x] = palette[(int)src[y*client->rectWidth+x]]; +  } +} + +#if BPP != 8 + +/*---------------------------------------------------------------------------- + * + * JPEG decompression. + * + */ + +static rfbBool +DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) +{ +  struct jpeg_decompress_struct cinfo; +  struct jpeg_error_mgr jerr; +  int compressedLen; +  uint8_t *compressedData; +  CARDBPP *pixelPtr; +  JSAMPROW rowPointer[1]; +  int dx, dy; + +  compressedLen = (int)ReadCompactLen(client); +  if (compressedLen <= 0) { +    rfbClientLog("Incorrect data received from the server.\n"); +    return FALSE; +  } + +  compressedData = malloc(compressedLen); +  if (compressedData == NULL) { +    rfbClientLog("Memory allocation error.\n"); +    return FALSE; +  } + +  if (!ReadFromRFBServer(client, (char*)compressedData, compressedLen)) { +    free(compressedData); +    return FALSE; +  } + +  cinfo.err = jpeg_std_error(&jerr); +  cinfo.client_data = client; +  jpeg_create_decompress(&cinfo); + +  JpegSetSrcManager(&cinfo, compressedData, compressedLen); + +  jpeg_read_header(&cinfo, TRUE); +  cinfo.out_color_space = JCS_RGB; + +  jpeg_start_decompress(&cinfo); +  if (cinfo.output_width != w || cinfo.output_height != h || +      cinfo.output_components != 3) { +    rfbClientLog("Tight Encoding: Wrong JPEG data received.\n"); +    jpeg_destroy_decompress(&cinfo); +    free(compressedData); +    return FALSE; +  } + +  rowPointer[0] = (JSAMPROW)client->buffer; +  dy = 0; +  while (cinfo.output_scanline < cinfo.output_height) { +    jpeg_read_scanlines(&cinfo, rowPointer, 1); +    if (client->jpegError) { +      break; +    } +    pixelPtr = (CARDBPP *)&client->buffer[RFB_BUFFER_SIZE / 2]; +    for (dx = 0; dx < w; dx++) { +      *pixelPtr++ = +	RGB24_TO_PIXEL(BPP, client->buffer[dx*3], client->buffer[dx*3+1], client->buffer[dx*3+2]); +    } +    CopyRectangle(client, (uint8_t *)&client->buffer[RFB_BUFFER_SIZE / 2], x, y + dy, w, 1); +    dy++; +  } + +  if (!client->jpegError) +    jpeg_finish_decompress(&cinfo); + +  jpeg_destroy_decompress(&cinfo); +  free(compressedData); + +  return !client->jpegError; +} + +#else + +static long +ReadCompactLen (rfbClient* client) +{ +  long len; +  uint8_t b; + +  if (!ReadFromRFBServer(client, (char *)&b, 1)) +    return -1; +  len = (int)b & 0x7F; +  if (b & 0x80) { +    if (!ReadFromRFBServer(client, (char *)&b, 1)) +      return -1; +    len |= ((int)b & 0x7F) << 7; +    if (b & 0x80) { +      if (!ReadFromRFBServer(client, (char *)&b, 1)) +	return -1; +      len |= ((int)b & 0xFF) << 14; +    } +  } +  return len; +} + +/* + * JPEG source manager functions for JPEG decompression in Tight decoder. + */ + +static void +JpegInitSource(j_decompress_ptr cinfo) +{ +  rfbClient* client=(rfbClient*)cinfo->client_data; +  client->jpegError = FALSE; +} + +static boolean +JpegFillInputBuffer(j_decompress_ptr cinfo) +{ +  rfbClient* client=(rfbClient*)cinfo->client_data; +  client->jpegError = TRUE; +  client->jpegSrcManager->bytes_in_buffer = client->jpegBufferLen; +  client->jpegSrcManager->next_input_byte = (JOCTET *)client->jpegBufferPtr; + +  return TRUE; +} + +static void +JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes) +{ +  rfbClient* client=(rfbClient*)cinfo->client_data; +  if (num_bytes < 0 || num_bytes > client->jpegSrcManager->bytes_in_buffer) { +    client->jpegError = TRUE; +    client->jpegSrcManager->bytes_in_buffer = client->jpegBufferLen; +    client->jpegSrcManager->next_input_byte = (JOCTET *)client->jpegBufferPtr; +  } else { +    client->jpegSrcManager->next_input_byte += (size_t) num_bytes; +    client->jpegSrcManager->bytes_in_buffer -= (size_t) num_bytes; +  } +} + +static void +JpegTermSource(j_decompress_ptr cinfo) +{ +  /* nothing to do here. */ +} + +static void +JpegSetSrcManager(j_decompress_ptr cinfo, +		  uint8_t *compressedData, +		  int compressedLen) +{ +  rfbClient* client=(rfbClient*)cinfo->client_data; +  client->jpegBufferPtr = compressedData; +  client->jpegBufferLen = (size_t)compressedLen; + +  if(client->jpegSrcManager == NULL) +    client->jpegSrcManager = malloc(sizeof(struct jpeg_source_mgr)); +  client->jpegSrcManager->init_source = JpegInitSource; +  client->jpegSrcManager->fill_input_buffer = JpegFillInputBuffer; +  client->jpegSrcManager->skip_input_data = JpegSkipInputData; +  client->jpegSrcManager->resync_to_restart = jpeg_resync_to_restart; +  client->jpegSrcManager->term_source = JpegTermSource; +  client->jpegSrcManager->next_input_byte = (JOCTET*)client->jpegBufferPtr; +  client->jpegSrcManager->bytes_in_buffer = client->jpegBufferLen; + +  cinfo->src = client->jpegSrcManager; +} + +#endif + +#undef CARDBPP + +/* LIBVNCSERVER_HAVE_LIBZ and LIBVNCSERVER_HAVE_LIBJPEG */ +#endif +#endif + diff --git a/3rdParty/LibVNC/src/libvncclient/tls.c b/3rdParty/LibVNC/src/libvncclient/tls.c new file mode 100644 index 0000000..206dbda --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/tls.c @@ -0,0 +1,496 @@ +/* + *  Copyright (C) 2009 Vic Lee. + * + *  This is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This software is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this software; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, + *  USA. + */ + +#include <rfb/rfbclient.h> +#include <errno.h> +#include "tls.h" + +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS + +static const int rfbCertTypePriority[] = { GNUTLS_CRT_X509, 0 }; +static const int rfbProtoPriority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 }; +static const int rfbKXPriority[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0}; +static const int rfbKXAnon[] = {GNUTLS_KX_ANON_DH, 0}; + +#define DH_BITS 1024 +static gnutls_dh_params_t rfbDHParams; + +static rfbBool rfbTLSInitialized = FALSE; + +static rfbBool +InitializeTLS(void) +{ +  int ret; + +  if (rfbTLSInitialized) return TRUE; +  if ((ret = gnutls_global_init()) < 0 || +      (ret = gnutls_dh_params_init(&rfbDHParams)) < 0 || +      (ret = gnutls_dh_params_generate2(rfbDHParams, DH_BITS)) < 0) +  { +    rfbClientLog("Failed to initialized GnuTLS: %s.\n", gnutls_strerror(ret)); +    return FALSE; +  } +  rfbClientLog("GnuTLS initialized.\n"); +  rfbTLSInitialized = TRUE; +  return TRUE; +} + +static ssize_t +PushTLS(gnutls_transport_ptr_t transport, const void *data, size_t len) +{ +  rfbClient *client = (rfbClient*)transport; +  int ret; + +  while (1) +  { +    ret = write(client->sock, data, len); +    if (ret < 0) +    { +      if (errno == EINTR) continue; +      return -1; +    } +    return ret; +  } +} + + +static ssize_t +PullTLS(gnutls_transport_ptr_t transport, void *data, size_t len) +{ +  rfbClient *client = (rfbClient*)transport; +  int ret; + +  while (1) +  { +    ret = read(client->sock, data, len); +    if (ret < 0) +    { +      if (errno == EINTR) continue; +      return -1; +    } +    return ret; +  } +} + +static rfbBool +InitializeTLSSession(rfbClient* client, rfbBool anonTLS) +{ +  int ret; + +  if (client->tlsSession) return TRUE; + +  if ((ret = gnutls_init(&client->tlsSession, GNUTLS_CLIENT)) < 0) +  { +    rfbClientLog("Failed to initialized TLS session: %s.\n", gnutls_strerror(ret)); +    return FALSE; +  } + +  if ((ret = gnutls_set_default_priority(client->tlsSession)) < 0 || +      (ret = gnutls_kx_set_priority(client->tlsSession, anonTLS ? rfbKXAnon : rfbKXPriority)) < 0 || +      (ret = gnutls_certificate_type_set_priority(client->tlsSession, rfbCertTypePriority)) < 0 || +      (ret = gnutls_protocol_set_priority(client->tlsSession, rfbProtoPriority)) < 0) +  { +    FreeTLS(client); +    rfbClientLog("Failed to set TLS priority: %s.\n", gnutls_strerror(ret)); +    return FALSE; +  } + +  gnutls_transport_set_ptr(client->tlsSession, (gnutls_transport_ptr_t)client); +  gnutls_transport_set_push_function(client->tlsSession, PushTLS); +  gnutls_transport_set_pull_function(client->tlsSession, PullTLS); + +  rfbClientLog("TLS session initialized.\n"); + +  return TRUE; +} + +static rfbBool +SetTLSAnonCredential(rfbClient* client) +{ +  gnutls_anon_client_credentials anonCred; +  int ret; + +  if ((ret = gnutls_anon_allocate_client_credentials(&anonCred)) < 0 || +      (ret = gnutls_credentials_set(client->tlsSession, GNUTLS_CRD_ANON, anonCred)) < 0) +  { +    FreeTLS(client); +    rfbClientLog("Failed to create anonymous credentials: %s", gnutls_strerror(ret)); +    return FALSE; +  } +  rfbClientLog("TLS anonymous credential created.\n"); +  return TRUE; +} + +static rfbBool +HandshakeTLS(rfbClient* client) +{ +  int timeout = 15; +  int ret; + +  while (timeout > 0 && (ret = gnutls_handshake(client->tlsSession)) < 0) +  { +    if (!gnutls_error_is_fatal(ret)) +    { +      rfbClientLog("TLS handshake blocking.\n"); +      sleep(1); +      timeout--; +      continue; +    } +    rfbClientLog("TLS handshake failed: %s.\n", gnutls_strerror(ret)); +    FreeTLS(client); +    return FALSE; +  } + +  if (timeout <= 0) +  { +    rfbClientLog("TLS handshake timeout.\n"); +    FreeTLS(client); +    return FALSE; +  } + +  rfbClientLog("TLS handshake done.\n"); +  return TRUE; +} + +/* VeNCrypt sub auth. 1 byte auth count, followed by count * 4 byte integers */ +static rfbBool +ReadVeNCryptSecurityType(rfbClient* client, uint32_t *result) +{ +    uint8_t count=0; +    uint8_t loop=0; +    uint8_t flag=0; +    uint32_t tAuth[256], t; +    char buf1[500],buf2[10]; +    uint32_t authScheme; + +    if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE; + +    if (count==0) +    { +        rfbClientLog("List of security types is ZERO. Giving up.\n"); +        return FALSE; +    } +    if (count>sizeof(tAuth)) +    { +        rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth)); +        return FALSE; +    } + +    rfbClientLog("We have %d security types to read\n", count); +    authScheme=0; +    /* now, we have a list of available security types to read ( uint8_t[] ) */ +    for (loop=0;loop<count;loop++) +    { +        if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 4)) return FALSE; +        t=rfbClientSwap32IfLE(tAuth[loop]); +        rfbClientLog("%d) Received security type %d\n", loop, t); +        if (flag) continue; +        if (t==rfbVeNCryptTLSNone || +            t==rfbVeNCryptTLSVNC || +            t==rfbVeNCryptTLSPlain || +            t==rfbVeNCryptX509None || +            t==rfbVeNCryptX509VNC || +            t==rfbVeNCryptX509Plain) +        { +            flag++; +            authScheme=t; +            rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count); +            /* send back 4 bytes (in original byte order!) indicating which security type to use */ +            if (!WriteToRFBServer(client, (char *)&tAuth[loop], 4)) return FALSE; +        } +        tAuth[loop]=t; +    } +    if (authScheme==0) +    { +        memset(buf1, 0, sizeof(buf1)); +        for (loop=0;loop<count;loop++) +        { +            if (strlen(buf1)>=sizeof(buf1)-1) break; +            snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]); +            strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1); +        } +        rfbClientLog("Unknown VeNCrypt authentication scheme from VNC server: %s\n", +               buf1); +        return FALSE; +    } +    *result = authScheme; +    return TRUE; +} + +static void +FreeX509Credential(rfbCredential *cred) +{ +  if (cred->x509Credential.x509CACertFile) free(cred->x509Credential.x509CACertFile); +  if (cred->x509Credential.x509CACrlFile) free(cred->x509Credential.x509CACrlFile); +  if (cred->x509Credential.x509ClientCertFile) free(cred->x509Credential.x509ClientCertFile); +  if (cred->x509Credential.x509ClientKeyFile) free(cred->x509Credential.x509ClientKeyFile); +  free(cred); +} + +static gnutls_certificate_credentials_t +CreateX509CertCredential(rfbCredential *cred) +{ +  gnutls_certificate_credentials_t x509_cred; +  int ret; + +  if (!cred->x509Credential.x509CACertFile) +  { +    rfbClientLog("No CA certificate provided.\n"); +    return NULL; +  } + +  if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) +  { +    rfbClientLog("Cannot allocate credentials: %s.\n", gnutls_strerror(ret)); +    return NULL; +  } +  if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred, +    cred->x509Credential.x509CACertFile, GNUTLS_X509_FMT_PEM)) < 0) +  { +    rfbClientLog("Cannot load CA credentials: %s.\n", gnutls_strerror(ret)); +    gnutls_certificate_free_credentials (x509_cred); +    return NULL; +  } +  if (cred->x509Credential.x509ClientCertFile && cred->x509Credential.x509ClientKeyFile) +  { +    if ((ret = gnutls_certificate_set_x509_key_file(x509_cred, +      cred->x509Credential.x509ClientCertFile, cred->x509Credential.x509ClientKeyFile, +      GNUTLS_X509_FMT_PEM)) < 0) +    { +      rfbClientLog("Cannot load client certificate or key: %s.\n", gnutls_strerror(ret)); +      gnutls_certificate_free_credentials (x509_cred); +      return NULL; +    } +  } else +  { +    rfbClientLog("No client certificate or key provided.\n"); +  } +  if (cred->x509Credential.x509CACrlFile) +  { +    if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred, +      cred->x509Credential.x509CACrlFile, GNUTLS_X509_FMT_PEM)) < 0) +    { +      rfbClientLog("Cannot load CRL: %s.\n", gnutls_strerror(ret)); +      gnutls_certificate_free_credentials (x509_cred); +      return NULL; +    } +  } else +  { +    rfbClientLog("No CRL provided.\n"); +  } +  gnutls_certificate_set_dh_params (x509_cred, rfbDHParams); +  return x509_cred; +} + +#endif + +rfbBool +HandleAnonTLSAuth(rfbClient* client) +{ +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS + +  if (!InitializeTLS() || !InitializeTLSSession(client, TRUE)) return FALSE; + +  if (!SetTLSAnonCredential(client)) return FALSE; + +  if (!HandshakeTLS(client)) return FALSE; + +  return TRUE; + +#else +  rfbClientLog("TLS is not supported.\n"); +  return FALSE; +#endif +} + +rfbBool +HandleVeNCryptAuth(rfbClient* client) +{ +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +  uint8_t major, minor, status; +  uint32_t authScheme; +  rfbBool anonTLS; +  gnutls_certificate_credentials_t x509_cred = NULL; +  int ret; + +  if (!InitializeTLS()) return FALSE; + +  /* Read VeNCrypt version */ +  if (!ReadFromRFBServer(client, (char *)&major, 1) || +      !ReadFromRFBServer(client, (char *)&minor, 1)) +  { +    return FALSE; +  } +  rfbClientLog("Got VeNCrypt version %d.%d from server.\n", (int)major, (int)minor); + +  if (major != 0 && minor != 2) +  { +    rfbClientLog("Unsupported VeNCrypt version.\n"); +    return FALSE; +  } + +  if (!WriteToRFBServer(client, (char *)&major, 1) || +      !WriteToRFBServer(client, (char *)&minor, 1) || +      !ReadFromRFBServer(client, (char *)&status, 1)) +  { +    return FALSE; +  } + +  if (status != 0) +  { +    rfbClientLog("Server refused VeNCrypt version %d.%d.\n", (int)major, (int)minor); +    return FALSE; +  } + +  if (!ReadVeNCryptSecurityType(client, &authScheme)) return FALSE; +  if (!ReadFromRFBServer(client, (char *)&status, 1) || status != 1) +  { +    rfbClientLog("Server refused VeNCrypt authentication %d (%d).\n", authScheme, (int)status); +    return FALSE; +  } +  client->subAuthScheme = authScheme; + +  /* Some VeNCrypt security types are anonymous TLS, others are X509 */ +  switch (authScheme) +  { +    case rfbVeNCryptTLSNone: +    case rfbVeNCryptTLSVNC: +    case rfbVeNCryptTLSPlain: +      anonTLS = TRUE; +      break; +    default: +      anonTLS = FALSE; +      break; +  } + +  /* Get X509 Credentials if it's not anonymous */ +  if (!anonTLS) +  { +    rfbCredential *cred; + +    if (!client->GetCredential) +    { +      rfbClientLog("GetCredential callback is not set.\n"); +      return FALSE; +    } +    cred = client->GetCredential(client, rfbCredentialTypeX509); +    if (!cred) +    { +      rfbClientLog("Reading credential failed\n"); +      return FALSE; +    } + +    x509_cred = CreateX509CertCredential(cred); +    FreeX509Credential(cred); +    if (!x509_cred) return FALSE; +  } + +  /* Start up the TLS session */ +  if (!InitializeTLSSession(client, anonTLS)) return FALSE; + +  if (anonTLS) +  { +    if (!SetTLSAnonCredential(client)) return FALSE; +  } +  else +  { +    if ((ret = gnutls_credentials_set(client->tlsSession, GNUTLS_CRD_CERTIFICATE, x509_cred)) < 0) +    { +      rfbClientLog("Cannot set x509 credential: %s.\n", gnutls_strerror(ret)); +      FreeTLS(client); +      return FALSE; +    } +  } + +  if (!HandshakeTLS(client)) return FALSE; + +  /* TODO: validate certificate */ + +  /* We are done here. The caller should continue with client->subAuthScheme +   * to do actual sub authentication. +   */ +  return TRUE; + +#else +  rfbClientLog("TLS is not supported.\n"); +  return FALSE; +#endif +} + +int +ReadFromTLS(rfbClient* client, char *out, unsigned int n) +{ +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +  ssize_t ret; + +  ret = gnutls_record_recv(client->tlsSession, out, n); +  if (ret >= 0) return ret; +  if (ret == GNUTLS_E_REHANDSHAKE || ret == GNUTLS_E_AGAIN) +  { +    errno = EAGAIN; +  } else +  { +    rfbClientLog("Error reading from TLS: %s.\n", gnutls_strerror(ret)); +    errno = EINTR; +  } +  return -1; +#else +  rfbClientLog("TLS is not supported.\n"); +  errno = EINTR; +  return -1; +#endif +} + +int +WriteToTLS(rfbClient* client, char *buf, unsigned int n) +{ +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +  unsigned int offset = 0; +  ssize_t ret; + +  while (offset < n) +  { +    ret = gnutls_record_send(client->tlsSession, buf+offset, (size_t)(n-offset)); +    if (ret == 0) continue; +    if (ret < 0) +    { +      if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) continue; +      rfbClientLog("Error writing to TLS: %s.\n", gnutls_strerror(ret)); +      return -1; +    } +    offset += (unsigned int)ret; +  } +  return offset; +#else +  rfbClientLog("TLS is not supported.\n"); +  errno = EINTR; +  return -1; +#endif +} + +void FreeTLS(rfbClient* client) +{ +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +  if (client->tlsSession) +  { +    gnutls_deinit(client->tlsSession); +    client->tlsSession = NULL; +  } +#endif +} diff --git a/3rdParty/LibVNC/src/libvncclient/tls.h b/3rdParty/LibVNC/src/libvncclient/tls.h new file mode 100644 index 0000000..48d159b --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/tls.h @@ -0,0 +1,51 @@ +#ifndef TLS_H +#define TLS_H + +/* + *  Copyright (C) 2009 Vic Lee. + * + *  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. + */ + +/* Handle Anonymous TLS Authentication (18) with the server. + * After authentication, client->tlsSession will be set. + */ +rfbBool HandleAnonTLSAuth(rfbClient* client); + +/* Handle VeNCrypt Authentication (19) with the server. + * The callback function GetX509Credential will be called. + * After authentication, client->tlsSession will be set. + */ +rfbBool HandleVeNCryptAuth(rfbClient* client); + +/* Read desired bytes from TLS session. + * It's a wrapper function over gnutls_record_recv() and return values + * are same as read(), that is, >0 for actual bytes read, 0 for EOF, + * or EAGAIN, EINTR. + * This should be a non-blocking call. Blocking is handled in sockets.c. + */ +int ReadFromTLS(rfbClient* client, char *out, unsigned int n); + +/* Write desired bytes to TLS session. + * It's a wrapper function over gnutls_record_send() and it will be + * blocking call, until all bytes are written or error returned. + */ +int WriteToTLS(rfbClient* client, char *buf, unsigned int n); + +/* Free TLS resources */ +void FreeTLS(rfbClient* client); + +#endif /* TLS_H */ diff --git a/3rdParty/LibVNC/src/libvncclient/ultra.c b/3rdParty/LibVNC/src/libvncclient/ultra.c new file mode 100644 index 0000000..3be150d --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/ultra.c @@ -0,0 +1,210 @@ +/* + *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved. + *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved. + * + *  This is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This software is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this software; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, + *  USA. + */ + +/* + * ultrazip.c - handle ultrazip 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 an zlib + * encoded rectangle with BPP bits per pixel. + */ + +#define HandleUltraZipBPP CONCAT2E(HandleUltraZip,BPP) +#define HandleUltraBPP CONCAT2E(HandleUltra,BPP) +#define CARDBPP CONCAT3E(uint,BPP,_t) + +static rfbBool +HandleUltraBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ +  rfbZlibHeader hdr; +  int toRead=0; +  int inflateResult=0; +  int uncompressedBytes = (( rw * rh ) * ( BPP / 8 )); + +  if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbZlibHeader)) +    return FALSE; + +  toRead = rfbClientSwap32IfLE(hdr.nBytes); +  if (toRead==0) return TRUE; + +  if (uncompressedBytes==0) +  { +      rfbClientLog("ultra error: rectangle has 0 uncomressed bytes ((%dw * %dh) * (%d / 8))\n", rw, rh, BPP);  +      return FALSE; +  } + +  /* First make sure we have a large enough raw buffer to hold the +   * decompressed data.  In practice, with a fixed BPP, fixed frame +   * buffer size and the first update containing the entire frame +   * buffer, this buffer allocation should only happen once, on the +   * first update. +   */ +  if ( client->raw_buffer_size < uncompressedBytes) { +    if ( client->raw_buffer != NULL ) { +      free( client->raw_buffer ); +    } +    client->raw_buffer_size = uncompressedBytes; +    /* buffer needs to be aligned on 4-byte boundaries */ +    if ((client->raw_buffer_size % 4)!=0) +      client->raw_buffer_size += (4-(client->raw_buffer_size % 4)); +    client->raw_buffer = (char*) malloc( client->raw_buffer_size ); +  } +   +  /* allocate enough space to store the incoming compressed packet */ +  if ( client->ultra_buffer_size < toRead ) { +    if ( client->ultra_buffer != NULL ) { +      free( client->ultra_buffer ); +    } +    client->ultra_buffer_size = toRead; +    /* buffer needs to be aligned on 4-byte boundaries */ +    if ((client->ultra_buffer_size % 4)!=0) +      client->ultra_buffer_size += (4-(client->ultra_buffer_size % 4)); +    client->ultra_buffer = (char*) malloc( client->ultra_buffer_size ); +  } + +  /* Fill the buffer, obtaining data from the server. */ +  if (!ReadFromRFBServer(client, client->ultra_buffer, toRead)) +      return FALSE; + +  /* uncompress the data */ +  uncompressedBytes = client->raw_buffer_size; +  inflateResult = lzo1x_decompress( +              (lzo_byte *)client->ultra_buffer, toRead, +              (lzo_byte *)client->raw_buffer, (lzo_uintp) &uncompressedBytes, +              NULL); +   +   +  if ((rw * rh * (BPP / 8)) != uncompressedBytes) +      rfbClientLog("Ultra decompressed too little (%d < %d)", (rw * rh * (BPP / 8)), uncompressedBytes); +   +  /* Put the uncompressed contents of the update on the screen. */ +  if ( inflateResult == LZO_E_OK )  +  { +    CopyRectangle(client, (unsigned char *)client->raw_buffer, rx, ry, rw, rh); +  } +  else +  { +    rfbClientLog("ultra decompress returned error: %d\n", +            inflateResult); +    return FALSE; +  } +  return TRUE; +} + + +/* UltraZip is like rre in that it is composed of subrects */ +static rfbBool +HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ +  rfbZlibHeader hdr; +  int i=0; +  int toRead=0; +  int inflateResult=0; +  unsigned char *ptr=NULL; +  int uncompressedBytes = ry + (rw * 65535); +  unsigned int numCacheRects = rx; + +  if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbZlibHeader)) +    return FALSE; + +  toRead = rfbClientSwap32IfLE(hdr.nBytes); + +  if (toRead==0) return TRUE; + +  if (uncompressedBytes==0) +  { +      rfbClientLog("ultrazip error: rectangle has 0 uncomressed bytes (%dy + (%dw * 65535)) (%d rectangles)\n", ry, rw, rx);  +      return FALSE; +  } + +  /* First make sure we have a large enough raw buffer to hold the +   * decompressed data.  In practice, with a fixed BPP, fixed frame +   * buffer size and the first update containing the entire frame +   * buffer, this buffer allocation should only happen once, on the +   * first update. +   */ +  if ( client->raw_buffer_size < (uncompressedBytes + 500)) { +    if ( client->raw_buffer != NULL ) { +      free( client->raw_buffer ); +    } +    client->raw_buffer_size = uncompressedBytes + 500; +    /* buffer needs to be aligned on 4-byte boundaries */ +    if ((client->raw_buffer_size % 4)!=0) +      client->raw_buffer_size += (4-(client->raw_buffer_size % 4)); +    client->raw_buffer = (char*) malloc( client->raw_buffer_size ); +  } + +  +  /* allocate enough space to store the incoming compressed packet */ +  if ( client->ultra_buffer_size < toRead ) { +    if ( client->ultra_buffer != NULL ) { +      free( client->ultra_buffer ); +    } +    client->ultra_buffer_size = toRead; +    client->ultra_buffer = (char*) malloc( client->ultra_buffer_size ); +  } + +  /* Fill the buffer, obtaining data from the server. */ +  if (!ReadFromRFBServer(client, client->ultra_buffer, toRead)) +      return FALSE; + +  /* uncompress the data */ +  uncompressedBytes = client->raw_buffer_size; +  inflateResult = lzo1x_decompress( +              (lzo_byte *)client->ultra_buffer, toRead, +              (lzo_byte *)client->raw_buffer, (lzo_uintp) &uncompressedBytes, NULL); +  if ( inflateResult != LZO_E_OK )  +  { +    rfbClientLog("ultra decompress returned error: %d\n", +            inflateResult); +    return FALSE; +  } +   +  /* Put the uncompressed contents of the update on the screen. */ +  ptr = (unsigned char *)client->raw_buffer; +  for (i=0; i<numCacheRects; i++) +  { +    unsigned short sx, sy, sw, sh; +    unsigned int se; + +    memcpy((char *)&sx, ptr, 2); ptr += 2; +    memcpy((char *)&sy, ptr, 2); ptr += 2; +    memcpy((char *)&sw, ptr, 2); ptr += 2; +    memcpy((char *)&sh, ptr, 2); ptr += 2; +    memcpy((char *)&se, ptr, 4); ptr += 4; + +    sx = rfbClientSwap16IfLE(sx); +    sy = rfbClientSwap16IfLE(sy); +    sw = rfbClientSwap16IfLE(sw); +    sh = rfbClientSwap16IfLE(sh); +    se = rfbClientSwap32IfLE(se); + +    if (se == rfbEncodingRaw) +    { +        CopyRectangle(client, (unsigned char *)ptr, sx, sy, sw, sh); +        ptr += ((sw * sh) * (BPP / 8)); +    } +  }   + +  return TRUE; +} + +#undef CARDBPP diff --git a/3rdParty/LibVNC/src/libvncclient/vncviewer.c b/3rdParty/LibVNC/src/libvncclient/vncviewer.c new file mode 100644 index 0000000..094ba34 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/vncviewer.c @@ -0,0 +1,375 @@ +/* + *  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. + */ + +/* + * vncviewer.c - the Xt-based VNC viewer. + */ + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#define _POSIX_SOURCE +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <rfb/rfbclient.h> +#include "tls.h" + +static void Dummy(rfbClient* client) { +} +static rfbBool DummyPoint(rfbClient* client, int x, int y) { +  return TRUE; +} +static void DummyRect(rfbClient* client, int x, int y, int w, int h) { +} + +#ifdef __MINGW32__ +static char* NoPassword(rfbClient* client) { +  return strdup(""); +} +#undef SOCKET +#include <winsock2.h> +#define close closesocket +#else +#include <stdio.h> +#include <termios.h> +#endif + +static char* ReadPassword(rfbClient* client) { +#ifdef __MINGW32__ +	/* FIXME */ +	rfbClientErr("ReadPassword on MinGW32 NOT IMPLEMENTED\n"); +	return NoPassword(client); +#else +	int i; +	char* p=malloc(9); +	struct termios save,noecho; +	p[0]=0; +	if(tcgetattr(fileno(stdin),&save)!=0) return p; +	noecho=save; noecho.c_lflag &= ~ECHO; +	if(tcsetattr(fileno(stdin),TCSAFLUSH,&noecho)!=0) return p; +	fprintf(stderr,"Password: "); +	i=0; +	while(1) { +		int c=fgetc(stdin); +		if(c=='\n') +			break; +		if(i<8) { +			p[i]=c; +			i++; +			p[i]=0; +		} +	} +	tcsetattr(fileno(stdin),TCSAFLUSH,&save); +	return p; +#endif +} +static rfbBool MallocFrameBuffer(rfbClient* client) { +  if(client->frameBuffer) +    free(client->frameBuffer); +  client->frameBuffer=malloc(client->width*client->height*client->format.bitsPerPixel/8); +  return client->frameBuffer?TRUE:FALSE; +} + +static void initAppData(AppData* data) { +	data->shareDesktop=TRUE; +	data->viewOnly=FALSE; +	data->encodingsString="tight zrle ultra copyrect hextile zlib corre rre raw"; +	data->useBGR233=FALSE; +	data->nColours=0; +	data->forceOwnCmap=FALSE; +	data->forceTrueColour=FALSE; +	data->requestedDepth=0; +	data->compressLevel=3; +	data->qualityLevel=5; +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +	data->enableJPEG=TRUE; +#else +	data->enableJPEG=FALSE; +#endif +	data->useRemoteCursor=FALSE; +} + +rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, +			int bytesPerPixel) { +  rfbClient* client=(rfbClient*)calloc(sizeof(rfbClient),1); +  if(!client) { +    rfbClientErr("Couldn't allocate client structure!\n"); +    return NULL; +  } +  initAppData(&client->appData); +  client->endianTest = 1; +  client->programName=""; +  client->serverHost=strdup(""); +  client->serverPort=5900; + +  client->destHost = NULL; +  client->destPort = 5900; +   +  client->CurrentKeyboardLedState = 0; +  client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint; + +  /* default: use complete frame buffer */  +  client->updateRect.x = -1; +  +  client->format.bitsPerPixel = bytesPerPixel*8; +  client->format.depth = bitsPerSample*samplesPerPixel; +  client->appData.requestedDepth=client->format.depth; +  client->format.bigEndian = *(char *)&client->endianTest?FALSE:TRUE; +  client->format.trueColour = TRUE; + +  if (client->format.bitsPerPixel == 8) { +    client->format.redMax = 7; +    client->format.greenMax = 7; +    client->format.blueMax = 3; +    client->format.redShift = 0; +    client->format.greenShift = 3; +    client->format.blueShift = 6; +  } else { +    client->format.redMax = (1 << bitsPerSample) - 1; +    client->format.greenMax = (1 << bitsPerSample) - 1; +    client->format.blueMax = (1 << bitsPerSample) - 1; +    if(!client->format.bigEndian) { +      client->format.redShift = 0; +      client->format.greenShift = bitsPerSample; +      client->format.blueShift = bitsPerSample * 2; +    } else { +      if(client->format.bitsPerPixel==8*3) { +	client->format.redShift = bitsPerSample*2; +	client->format.greenShift = bitsPerSample*1; +	client->format.blueShift = 0; +      } else { +	client->format.redShift = bitsPerSample*3; +	client->format.greenShift = bitsPerSample*2; +	client->format.blueShift = bitsPerSample; +      } +    } +  } + +  client->bufoutptr=client->buf; +  client->buffered=0; + +#ifdef LIBVNCSERVER_HAVE_LIBZ +  client->raw_buffer_size = -1; +  client->decompStreamInited = FALSE; + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +  memset(client->zlibStreamActive,0,sizeof(rfbBool)*4); +  client->jpegSrcManager = NULL; +#endif +#endif + +  client->HandleCursorPos = DummyPoint; +  client->SoftCursorLockArea = DummyRect; +  client->SoftCursorUnlockScreen = Dummy; +  client->GotFrameBufferUpdate = DummyRect; +  client->FinishedFrameBufferUpdate = NULL; +  client->GetPassword = ReadPassword; +  client->MallocFrameBuffer = MallocFrameBuffer; +  client->Bell = Dummy; +  client->CurrentKeyboardLedState = 0; +  client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint; + +  client->authScheme = 0; +  client->subAuthScheme = 0; +  client->GetCredential = NULL; +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +  client->tlsSession = NULL; +#endif +  client->sock = -1; +  client->listenSock = -1; +  client->clientAuthSchemes = NULL; +  return client; +} + +static rfbBool rfbInitConnection(rfbClient* client) +{ +  /* Unless we accepted an incoming connection, make a TCP connection to the +     given VNC server */ + +  if (!client->listenSpecified) { +    if (!client->serverHost) +      return FALSE; +    if (client->destHost) { +      if (!ConnectToRFBRepeater(client,client->serverHost,client->serverPort,client->destHost,client->destPort)) +        return FALSE; +    } else { +      if (!ConnectToRFBServer(client,client->serverHost,client->serverPort)) +        return FALSE; +    } +  } + +  /* Initialise the VNC connection, including reading the password */ + +  if (!InitialiseRFBConnection(client)) +    return FALSE; + +  if (!SetFormatAndEncodings(client)) +    return FALSE; + +  client->width=client->si.framebufferWidth; +  client->height=client->si.framebufferHeight; +  client->MallocFrameBuffer(client); + +  if (client->updateRect.x < 0) { +    client->updateRect.x = client->updateRect.y = 0; +    client->updateRect.w = client->width; +    client->updateRect.h = client->height; +  } + +  if (client->appData.scaleSetting>1) +  { +      if (!SendScaleSetting(client, client->appData.scaleSetting)) +          return FALSE; +      if (!SendFramebufferUpdateRequest(client, +			      client->updateRect.x / client->appData.scaleSetting, +			      client->updateRect.y / client->appData.scaleSetting, +			      client->updateRect.w / client->appData.scaleSetting, +			      client->updateRect.h / client->appData.scaleSetting, +			      FALSE)) +	      return FALSE; +  } +  else +  { +      if (!SendFramebufferUpdateRequest(client, +			      client->updateRect.x, client->updateRect.y, +			      client->updateRect.w, client->updateRect.h, +			      FALSE)) +      return FALSE; +  } + +  return TRUE; +} + +rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) { +  int i,j; + +  if(argv && argc && *argc) { +    if(client->programName==0) +      client->programName=argv[0]; + +    for (i = 1; i < *argc; i++) { +      j = i; +      if (strcmp(argv[i], "-listen") == 0) { +	listenForIncomingConnections(client); +	break; +      } else if (strcmp(argv[i], "-listennofork") == 0) { +	listenForIncomingConnectionsNoFork(client, -1); +	break; +      } else if (strcmp(argv[i], "-play") == 0) { +	client->serverPort = -1; +	j++; +      } else if (i+1<*argc && strcmp(argv[i], "-encodings") == 0) { +	client->appData.encodingsString = argv[i+1]; +	j+=2; +      } else if (i+1<*argc && strcmp(argv[i], "-compress") == 0) { +	client->appData.compressLevel = atoi(argv[i+1]); +	j+=2; +      } else if (i+1<*argc && strcmp(argv[i], "-quality") == 0) { +	client->appData.qualityLevel = atoi(argv[i+1]); +	j+=2; +      } else if (i+1<*argc && strcmp(argv[i], "-scale") == 0) { +        client->appData.scaleSetting = atoi(argv[i+1]); +        j+=2; +      } else if (i+1<*argc && strcmp(argv[i], "-repeaterdest") == 0) { +	char* colon=strchr(argv[i+1],':'); + +	if(client->destHost) +	  free(client->destHost); +        client->destPort = 5900; + +	client->destHost = strdup(argv[i+1]); +	if(colon) { +	  client->destHost[(int)(colon-argv[i+1])] = '\0'; +	  client->destPort = atoi(colon+1); +	} +        j+=2; +      } else { +	char* colon=strchr(argv[i],':'); + +	if(client->serverHost) +	  free(client->serverHost); + +	if(colon) { +	  client->serverHost = strdup(argv[i]); +	  client->serverHost[(int)(colon-argv[i])] = '\0'; +	  client->serverPort = atoi(colon+1); +	} else { +	  client->serverHost = strdup(argv[i]); +	} +	if(client->serverPort >= 0 && client->serverPort < 5900) +	  client->serverPort += 5900; +      } +      /* purge arguments */ +      if (j>i) { +	*argc-=j-i; +	memmove(argv+i,argv+j,(*argc-i)*sizeof(char*)); +	i--; +      } +    } +  } + +  if(!rfbInitConnection(client)) { +    rfbClientCleanup(client); +    return FALSE; +  } + +  return TRUE; +} + +void rfbClientCleanup(rfbClient* client) { +#ifdef LIBVNCSERVER_HAVE_LIBZ +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +  int i; + +  for ( i = 0; i < 4; i++ ) { +    if (client->zlibStreamActive[i] == TRUE ) { +      if (inflateEnd (&client->zlibStream[i]) != Z_OK && +	  client->zlibStream[i].msg != NULL) +	rfbClientLog("inflateEnd: %s\n", client->zlibStream[i].msg); +    } +  } + +  if ( client->decompStreamInited == TRUE ) { +    if (inflateEnd (&client->decompStream) != Z_OK && +	client->decompStream.msg != NULL) +      rfbClientLog("inflateEnd: %s\n", client->decompStream.msg ); +  } + +  if (client->jpegSrcManager) +    free(client->jpegSrcManager); +#endif +#endif + +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +  FreeTLS(client); +#endif +  if (client->sock >= 0) +    close(client->sock); +  if (client->listenSock >= 0) +    close(client->listenSock); +  free(client->desktopName); +  free(client->serverHost); +  if (client->destHost) +    free(client->destHost); +  if (client->clientAuthSchemes) +    free(client->clientAuthSchemes); +  free(client); +} diff --git a/3rdParty/LibVNC/src/libvncclient/zlib.c b/3rdParty/LibVNC/src/libvncclient/zlib.c new file mode 100644 index 0000000..e872d40 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/zlib.c @@ -0,0 +1,162 @@ +/* + *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved. + *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved. + * + *  This is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This software is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this software; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, + *  USA. + */ + +#ifdef LIBVNCSERVER_HAVE_LIBZ + +/* + * zlib.c - handle zlib 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 an zlib + * encoded rectangle with BPP bits per pixel. + */ + +#define HandleZlibBPP CONCAT2E(HandleZlib,BPP) +#define CARDBPP CONCAT3E(uint,BPP,_t) + +static rfbBool +HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ +  rfbZlibHeader hdr; +  int remaining; +  int inflateResult; +  int toRead; + +  /* First make sure we have a large enough raw buffer to hold the +   * decompressed data.  In practice, with a fixed BPP, fixed frame +   * buffer size and the first update containing the entire frame +   * buffer, this buffer allocation should only happen once, on the +   * first update. +   */ +  if ( client->raw_buffer_size < (( rw * rh ) * ( BPP / 8 ))) { + +    if ( client->raw_buffer != NULL ) { + +      free( client->raw_buffer ); + +    } + +    client->raw_buffer_size = (( rw * rh ) * ( BPP / 8 )); +    client->raw_buffer = (char*) malloc( client->raw_buffer_size ); + +  } + +  if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbZlibHeader)) +    return FALSE; + +  remaining = rfbClientSwap32IfLE(hdr.nBytes); + +  /* Need to initialize the decompressor state. */ +  client->decompStream.next_in   = ( Bytef * )client->buffer; +  client->decompStream.avail_in  = 0; +  client->decompStream.next_out  = ( Bytef * )client->raw_buffer; +  client->decompStream.avail_out = client->raw_buffer_size; +  client->decompStream.data_type = Z_BINARY; + +  /* Initialize the decompression stream structures on the first invocation. */ +  if ( client->decompStreamInited == FALSE ) { + +    inflateResult = inflateInit( &client->decompStream ); + +    if ( inflateResult != Z_OK ) { +      rfbClientLog( +              "inflateInit returned error: %d, msg: %s\n", +              inflateResult, +              client->decompStream.msg); +      return FALSE; +    } + +    client->decompStreamInited = TRUE; + +  } + +  inflateResult = Z_OK; + +  /* Process buffer full of data until no more to process, or +   * some type of inflater error, or Z_STREAM_END. +   */ +  while (( remaining > 0 ) && +         ( inflateResult == Z_OK )) { +   +    if ( remaining > RFB_BUFFER_SIZE ) { +      toRead = RFB_BUFFER_SIZE; +    } +    else { +      toRead = remaining; +    } + +    /* Fill the buffer, obtaining data from the server. */ +    if (!ReadFromRFBServer(client, client->buffer,toRead)) +      return FALSE; + +    client->decompStream.next_in  = ( Bytef * )client->buffer; +    client->decompStream.avail_in = toRead; + +    /* Need to uncompress buffer full. */ +    inflateResult = inflate( &client->decompStream, Z_SYNC_FLUSH ); + +    /* We never supply a dictionary for compression. */ +    if ( inflateResult == Z_NEED_DICT ) { +      rfbClientLog("zlib inflate needs a dictionary!\n"); +      return FALSE; +    } +    if ( inflateResult < 0 ) { +      rfbClientLog( +              "zlib inflate returned error: %d, msg: %s\n", +              inflateResult, +              client->decompStream.msg); +      return FALSE; +    } + +    /* Result buffer allocated to be at least large enough.  We should +     * never run out of space! +     */ +    if (( client->decompStream.avail_in > 0 ) && +        ( client->decompStream.avail_out <= 0 )) { +      rfbClientLog("zlib inflate ran out of space!\n"); +      return FALSE; +    } + +    remaining -= toRead; + +  } /* while ( remaining > 0 ) */ + +  if ( inflateResult == Z_OK ) { + +    /* Put the uncompressed contents of the update on the screen. */ +    CopyRectangle(client, (uint8_t *)client->raw_buffer, rx, ry, rw, rh); +  } +  else { + +    rfbClientLog( +            "zlib inflate returned error: %d, msg: %s\n", +            inflateResult, +            client->decompStream.msg); +    return FALSE; + +  } + +  return TRUE; +} + +#undef CARDBPP + +#endif diff --git a/3rdParty/LibVNC/src/libvncclient/zrle.c b/3rdParty/LibVNC/src/libvncclient/zrle.c new file mode 100644 index 0000000..da2db4b --- /dev/null +++ b/3rdParty/LibVNC/src/libvncclient/zrle.c @@ -0,0 +1,427 @@ +/* + *  Copyright (C) 2005 Johannes E. Schindelin.  All Rights Reserved. + * + *  This is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This software is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this software; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, + *  USA. + */ + +#ifdef LIBVNCSERVER_HAVE_LIBZ + +/* + * zrle.c - handle zrle 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 an zrle + * encoded rectangle with BPP bits per pixel. + */ + +#ifndef REALBPP +#define REALBPP BPP +#endif + +#if !defined(UNCOMP) || UNCOMP==0 +#define HandleZRLE CONCAT2E(HandleZRLE,REALBPP) +#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) +#elif UNCOMP>0 +#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Down) +#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Down) +#else +#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Up) +#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Up) +#endif +#define CARDBPP CONCAT3E(uint,BPP,_t) +#define CARDREALBPP CONCAT3E(uint,REALBPP,_t) + +#define ENDIAN_LITTLE 0 +#define ENDIAN_BIG 1 +#define ENDIAN_NO 2 +#define ZYWRLE_ENDIAN ENDIAN_LITTLE +#undef END_FIX +#if ZYWRLE_ENDIAN == ENDIAN_LITTLE +#  define END_FIX LE +#elif ZYWRLE_ENDIAN == ENDIAN_BIG +#  define END_FIX BE +#else +#  define END_FIX NE +#endif +#define __RFB_CONCAT3E(a,b,c) CONCAT3E(a,b,c) +#define __RFB_CONCAT2E(a,b) CONCAT2E(a,b) +#undef CPIXEL +#if REALBPP != BPP +#if UNCOMP == 0 +#define CPIXEL REALBPP +#elif UNCOMP>0 +#define CPIXEL CONCAT2E(REALBPP,Down) +#else +#define CPIXEL CONCAT2E(REALBPP,Up) +#endif +#endif +#define PIXEL_T __RFB_CONCAT3E(uint,BPP,_t) +#if BPP!=8 +#define ZYWRLE_DECODE 1 +#include "../libvncserver/zywrletemplate.c" +#endif +#undef CPIXEL + +static int HandleZRLETile(rfbClient* client, +	uint8_t* buffer,size_t buffer_length, +	int x,int y,int w,int h); + +static rfbBool +HandleZRLE (rfbClient* client, int rx, int ry, int rw, int rh) +{ +	rfbZRLEHeader header; +	int remaining; +	int inflateResult; +	int toRead; +	int min_buffer_size = rw * rh * (REALBPP / 8) * 2; + +	/* First make sure we have a large enough raw buffer to hold the +	 * decompressed data.  In practice, with a fixed REALBPP, fixed frame +	 * buffer size and the first update containing the entire frame +	 * buffer, this buffer allocation should only happen once, on the +	 * first update. +	 */ +	if ( client->raw_buffer_size < min_buffer_size) { + +		if ( client->raw_buffer != NULL ) { + +			free( client->raw_buffer ); + +		} + +		client->raw_buffer_size = min_buffer_size; +		client->raw_buffer = (char*) malloc( client->raw_buffer_size ); + +	} + +	if (!ReadFromRFBServer(client, (char *)&header, sz_rfbZRLEHeader)) +		return FALSE; + +	remaining = rfbClientSwap32IfLE(header.length); + +	/* Need to initialize the decompressor state. */ +	client->decompStream.next_in   = ( Bytef * )client->buffer; +	client->decompStream.avail_in  = 0; +	client->decompStream.next_out  = ( Bytef * )client->raw_buffer; +	client->decompStream.avail_out = client->raw_buffer_size; +	client->decompStream.data_type = Z_BINARY; + +	/* Initialize the decompression stream structures on the first invocation. */ +	if ( client->decompStreamInited == FALSE ) { + +		inflateResult = inflateInit( &client->decompStream ); + +		if ( inflateResult != Z_OK ) { +			rfbClientLog( +					"inflateInit returned error: %d, msg: %s\n", +					inflateResult, +					client->decompStream.msg); +			return FALSE; +		} + +		client->decompStreamInited = TRUE; + +	} + +	inflateResult = Z_OK; + +	/* Process buffer full of data until no more to process, or +	 * some type of inflater error, or Z_STREAM_END. +	 */ +	while (( remaining > 0 ) && +			( inflateResult == Z_OK )) { + +		if ( remaining > RFB_BUFFER_SIZE ) { +			toRead = RFB_BUFFER_SIZE; +		} +		else { +			toRead = remaining; +		} + +		/* Fill the buffer, obtaining data from the server. */ +		if (!ReadFromRFBServer(client, client->buffer,toRead)) +			return FALSE; + +		client->decompStream.next_in  = ( Bytef * )client->buffer; +		client->decompStream.avail_in = toRead; + +		/* Need to uncompress buffer full. */ +		inflateResult = inflate( &client->decompStream, Z_SYNC_FLUSH ); + +		/* We never supply a dictionary for compression. */ +		if ( inflateResult == Z_NEED_DICT ) { +			rfbClientLog("zlib inflate needs a dictionary!\n"); +			return FALSE; +		} +		if ( inflateResult < 0 ) { +			rfbClientLog( +					"zlib inflate returned error: %d, msg: %s\n", +					inflateResult, +					client->decompStream.msg); +			return FALSE; +		} + +		/* Result buffer allocated to be at least large enough.  We should +		 * never run out of space! +		 */ +		if (( client->decompStream.avail_in > 0 ) && +				( client->decompStream.avail_out <= 0 )) { +			rfbClientLog("zlib inflate ran out of space!\n"); +			return FALSE; +		} + +		remaining -= toRead; + +	} /* while ( remaining > 0 ) */ + +	if ( inflateResult == Z_OK ) { +		void* buf=client->raw_buffer; +		int i,j; + +		remaining = client->raw_buffer_size-client->decompStream.avail_out; + +		for(j=0; j<rh; j+=rfbZRLETileHeight) +			for(i=0; i<rw; i+=rfbZRLETileWidth) { +				int subWidth=(i+rfbZRLETileWidth>rw)?rw-i:rfbZRLETileWidth; +				int subHeight=(j+rfbZRLETileHeight>rh)?rh-j:rfbZRLETileHeight; +				int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight); + +				if(result<0) { +					rfbClientLog("ZRLE decoding failed (%d)\n",result); +return TRUE; +					return FALSE; +				} + +				buf+=result; +				remaining-=result; +			} +	} +	else { + +		rfbClientLog( +				"zlib inflate returned error: %d, msg: %s\n", +				inflateResult, +				client->decompStream.msg); +		return FALSE; + +	} + +	return TRUE; +} + +#if REALBPP!=BPP && defined(UNCOMP) && UNCOMP!=0 +#if UNCOMP>0 +#define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)>>UNCOMP) +#else +#define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)<<(-(UNCOMP))) +#endif +#else +#define UncompressCPixel(pointer) (*(CARDBPP*)pointer) +#endif + +static int HandleZRLETile(rfbClient* client, +		uint8_t* buffer,size_t buffer_length, +		int x,int y,int w,int h) { +	uint8_t* buffer_copy = buffer; +	uint8_t* buffer_end = buffer+buffer_length; +	uint8_t type; +#if BPP!=8 +	uint8_t zywrle_level = (client->appData.qualityLevel & 0x80) ? +		0 : (3 - client->appData.qualityLevel / 3); +#endif + +	if(buffer_length<1) +		return -2; + +	type = *buffer; +	buffer++; +	{ +		if( type == 0 ) /* raw */ +#if BPP!=8 +          if( zywrle_level > 0 ){ +			CARDBPP* pFrame = (CARDBPP*)client->frameBuffer + y*client->width+x; +			int ret; +			client->appData.qualityLevel |= 0x80; +			ret = HandleZRLETile(client, buffer, buffer_end-buffer, x, y, w, h); +		    client->appData.qualityLevel &= 0x7F; +			if( ret < 0 ){ +				return ret; +			} +			ZYWRLE_SYNTHESIZE( pFrame, pFrame, w, h, client->width, zywrle_level, (int*)client->zlib_buffer ); +			buffer += ret; +		  }else +#endif +		{ +#if REALBPP!=BPP +			int i,j; + +			if(1+w*h*REALBPP/8>buffer_length) { +				rfbClientLog("expected %d bytes, got only %d (%dx%d)\n",1+w*h*REALBPP/8,buffer_length,w,h); +				return -3; +			} + +			for(j=y*client->width; j<(y+h)*client->width; j+=client->width) +				for(i=x; i<x+w; i++,buffer+=REALBPP/8) +					((CARDBPP*)client->frameBuffer)[j+i] = UncompressCPixel(buffer); +#else +			CopyRectangle(client, buffer, x, y, w, h); +			buffer+=w*h*REALBPP/8; +#endif +		} +		else if( type == 1 ) /* solid */ +		{ +			CARDBPP color = UncompressCPixel(buffer); + +			if(1+REALBPP/8>buffer_length) +				return -4; +				 +			FillRectangle(client, x, y, w, h, color); + +			buffer+=REALBPP/8; + +		} +		else if( (type >= 2)&&(type <= 127) ) /* packed Palette */ +		{ +			CARDBPP palette[16]; +			int i,j,shift, +				bpp=(type>4?(type>16?8:4):(type>2?2:1)), +				mask=(1<<bpp)-1, +				divider=(8/bpp); + +			if(1+type*REALBPP/8+((w+divider-1)/divider)*h>buffer_length) +				return -5; + +			/* read palette */ +			for(i=0; i<type; i++,buffer+=REALBPP/8) +				palette[i] = UncompressCPixel(buffer); + +			/* read palettized pixels */ +			for(j=y*client->width; j<(y+h)*client->width; j+=client->width) { +				for(i=x,shift=8-bpp; i<x+w; i++) { +					((CARDBPP*)client->frameBuffer)[j+i] = palette[((*buffer)>>shift)&mask]; +					shift-=bpp; +					if(shift<0) { +						shift=8-bpp; +						buffer++; +					} +				} +				if(shift<8-bpp) +					buffer++; +			} + +		} +		/* case 17 ... 127: not used, but valid */ +		else if( type == 128 ) /* plain RLE */ +		{ +			int i=0,j=0; +			while(j<h) { +				int color,length; +				/* read color */ +				if(buffer+REALBPP/8+1>buffer_end) +					return -7; +				color = UncompressCPixel(buffer); +				buffer+=REALBPP/8; +				/* read run length */ +				length=1; +				while(*buffer==0xff) { +					if(buffer+1>=buffer_end) +						return -8; +					length+=*buffer; +					buffer++; +				} +				length+=*buffer; +				buffer++; +				while(j<h && length>0) { +					((CARDBPP*)client->frameBuffer)[(y+j)*client->width+x+i] = color; +					length--; +					i++; +					if(i>=w) { +						i=0; +						j++; +					} +				} +				if(length>0) +					rfbClientLog("Warning: possible ZRLE corruption\n"); +			} + +		} +		else if( type == 129 ) /* unused */ +		{ +			return -8; +		} +		else if( (type >= 130)&&(type <= 255) ) /* palette RLE */ +		{ +			CARDBPP palette[128]; +			int i,j; + +			if(2+(type-128)*REALBPP/8>buffer_length) +				return -9; + +			/* read palette */ +			for(i=0; i<type-128; i++,buffer+=REALBPP/8) +				palette[i] = UncompressCPixel(buffer); +			/* read palettized pixels */ +			i=j=0; +			while(j<h) { +				int color,length; +				/* read color */ +				if(buffer>=buffer_end) +					return -10; +				color = palette[(*buffer)&0x7f]; +				length=1; +				if(*buffer&0x80) { +					if(buffer+1>=buffer_end) +						return -11; +					buffer++; +					/* read run length */ +					while(*buffer==0xff) { +						if(buffer+1>=buffer_end) +							return -8; +						length+=*buffer; +						buffer++; +					} +					length+=*buffer; +				} +				buffer++; +				while(j<h && length>0) { +					((CARDBPP*)client->frameBuffer)[(y+j)*client->width+x+i] = color; +					length--; +					i++; +					if(i>=w) { +						i=0; +						j++; +					} +				} +				if(length>0) +					rfbClientLog("Warning: possible ZRLE corruption\n"); +			} +		} +	} + +	return buffer-buffer_copy;	 +} + +#undef CARDBPP +#undef CARDREALBPP +#undef HandleZRLE +#undef HandleZRLETile +#undef UncompressCPixel +#undef REALBPP + +#endif + +#undef UNCOMP diff --git a/3rdParty/LibVNC/src/libvncserver/d3des.c b/3rdParty/LibVNC/src/libvncserver/d3des.c new file mode 100755 index 0000000..2df1aab --- /dev/null +++ b/3rdParty/LibVNC/src/libvncserver/d3des.c @@ -0,0 +1,436 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and + * triple-length support removed for use in VNC.  Also the bytebit[] array + * has been reversed so that the most significant bit in each byte of the + * key is ignored, not the least significant. + * + * These changes are: + *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* D3DES (V5.09) - + * + * A portable, public domain, version of the Data Encryption Standard. + * + * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. + * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation + * code;  Jim Gillogly & Phil Karn for the DES key schedule code; Dennis + * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau, + * for humouring me on. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. + * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. + */ + +#include "d3des.h" + +static void scrunch(unsigned char *, unsigned long *); +static void unscrun(unsigned long *, unsigned char *); +static void desfunc(unsigned long *, unsigned long *); +static void cookey(unsigned long *); + +static unsigned long KnL[32] = { 0L }; +/* +static unsigned long KnR[32] = { 0L }; +static unsigned long Kn3[32] = { 0L }; +static unsigned char Df_Key[24] = { +	0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, +	0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, +	0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 }; +*/ + +static unsigned short bytebit[8]	= { +	01, 02, 04, 010, 020, 040, 0100, 0200 }; + +static unsigned long bigbyte[24] = { +	0x800000L,	0x400000L,	0x200000L,	0x100000L, +	0x80000L,	0x40000L,	0x20000L,	0x10000L, +	0x8000L,	0x4000L,	0x2000L,	0x1000L, +	0x800L, 	0x400L, 	0x200L, 	0x100L, +	0x80L,		0x40L,		0x20L,		0x10L, +	0x8L,		0x4L,		0x2L,		0x1L	}; + +/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */ + +static unsigned char pc1[56] = { +	56, 48, 40, 32, 24, 16,  8,	 0, 57, 49, 41, 33, 25, 17, +	 9,  1, 58, 50, 42, 34, 26,	18, 10,  2, 59, 51, 43, 35, +	62, 54, 46, 38, 30, 22, 14,	 6, 61, 53, 45, 37, 29, 21, +	13,  5, 60, 52, 44, 36, 28,	20, 12,  4, 27, 19, 11,  3 }; + +static unsigned char totrot[16] = { +	1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; + +static unsigned char pc2[48] = { +	13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9, +	22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1, +	40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, +	43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; + +void rfbDesKey(unsigned char *key, +               int edf) +{ +	register int i, j, l, m, n; +	unsigned char pc1m[56], pcr[56]; +	unsigned long kn[32]; + +	for ( j = 0; j < 56; j++ ) { +		l = pc1[j]; +		m = l & 07; +		pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; +		} +	for( i = 0; i < 16; i++ ) { +		if( edf == DE1 ) m = (15 - i) << 1; +		else m = i << 1; +		n = m + 1; +		kn[m] = kn[n] = 0L; +		for( j = 0; j < 28; j++ ) { +			l = j + totrot[i]; +			if( l < 28 ) pcr[j] = pc1m[l]; +			else pcr[j] = pc1m[l - 28]; +			} +		for( j = 28; j < 56; j++ ) { +		    l = j + totrot[i]; +		    if( l < 56 ) pcr[j] = pc1m[l]; +		    else pcr[j] = pc1m[l - 28]; +		    } +		for( j = 0; j < 24; j++ ) { +			if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; +			if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; +			} +		} +	cookey(kn); +	return; +	} + +static void cookey(register unsigned long *raw1) +{ +	register unsigned long *cook, *raw0; +	unsigned long dough[32]; +	register int i; + +	cook = dough; +	for( i = 0; i < 16; i++, raw1++ ) { +		raw0 = raw1++; +		*cook	 = (*raw0 & 0x00fc0000L) << 6; +		*cook	|= (*raw0 & 0x00000fc0L) << 10; +		*cook	|= (*raw1 & 0x00fc0000L) >> 10; +		*cook++ |= (*raw1 & 0x00000fc0L) >> 6; +		*cook	 = (*raw0 & 0x0003f000L) << 12; +		*cook	|= (*raw0 & 0x0000003fL) << 16; +		*cook	|= (*raw1 & 0x0003f000L) >> 4; +		*cook++ |= (*raw1 & 0x0000003fL); +		} +	rfbUseKey(dough); +	return; +	} + +void rfbCPKey(register unsigned long *into) +{ +	register unsigned long *from, *endp; + +	from = KnL, endp = &KnL[32]; +	while( from < endp ) *into++ = *from++; +	return; +	} + +void rfbUseKey(register unsigned long *from) +{ +	register unsigned long *to, *endp; + +	to = KnL, endp = &KnL[32]; +	while( to < endp ) *to++ = *from++; +	return; +	} + +void rfbDes(unsigned char *inblock, +            unsigned char *outblock) +{ +	unsigned long work[2]; + +	scrunch(inblock, work); +	desfunc(work, KnL); +	unscrun(work, outblock); +	return; +	} + +static void scrunch(register unsigned char *outof, +                    register unsigned long *into) +{ +	*into	 = (*outof++ & 0xffL) << 24; +	*into	|= (*outof++ & 0xffL) << 16; +	*into	|= (*outof++ & 0xffL) << 8; +	*into++ |= (*outof++ & 0xffL); +	*into	 = (*outof++ & 0xffL) << 24; +	*into	|= (*outof++ & 0xffL) << 16; +	*into	|= (*outof++ & 0xffL) << 8; +	*into	|= (*outof   & 0xffL); +	return; +	} + +static void unscrun(register unsigned long *outof, +                    register unsigned char *into) +{ +	*into++ = (unsigned char)((*outof >> 24) & 0xffL); +	*into++ = (unsigned char)((*outof >> 16) & 0xffL); +	*into++ = (unsigned char)((*outof >>  8) & 0xffL); +	*into++ = (unsigned char)( *outof++	 & 0xffL); +	*into++ = (unsigned char)((*outof >> 24) & 0xffL); +	*into++ = (unsigned char)((*outof >> 16) & 0xffL); +	*into++ = (unsigned char)((*outof >>  8) & 0xffL); +	*into	= (unsigned char)( *outof	 & 0xffL); +	return; +	} + +static unsigned long SP1[64] = { +	0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, +	0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, +	0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, +	0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, +	0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, +	0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, +	0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, +	0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, +	0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, +	0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, +	0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, +	0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, +	0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, +	0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, +	0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, +	0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; + +static unsigned long SP2[64] = { +	0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, +	0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, +	0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, +	0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, +	0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, +	0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, +	0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, +	0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, +	0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, +	0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, +	0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, +	0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, +	0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, +	0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, +	0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, +	0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; + +static unsigned long SP3[64] = { +	0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, +	0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, +	0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, +	0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, +	0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, +	0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, +	0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, +	0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, +	0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, +	0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, +	0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, +	0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, +	0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, +	0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, +	0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, +	0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; + +static unsigned long SP4[64] = { +	0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, +	0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, +	0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, +	0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, +	0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, +	0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, +	0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, +	0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, +	0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, +	0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, +	0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, +	0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, +	0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, +	0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, +	0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, +	0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; + +static unsigned long SP5[64] = { +	0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, +	0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, +	0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, +	0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, +	0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, +	0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, +	0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, +	0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, +	0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, +	0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, +	0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, +	0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, +	0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, +	0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, +	0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, +	0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; + +static unsigned long SP6[64] = { +	0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, +	0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, +	0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, +	0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, +	0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, +	0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, +	0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, +	0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, +	0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, +	0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, +	0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, +	0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, +	0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, +	0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, +	0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, +	0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; + +static unsigned long SP7[64] = { +	0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, +	0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, +	0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, +	0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, +	0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, +	0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, +	0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, +	0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, +	0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, +	0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, +	0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, +	0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, +	0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, +	0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, +	0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, +	0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; + +static unsigned long SP8[64] = { +	0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, +	0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, +	0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, +	0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, +	0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, +	0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, +	0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, +	0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, +	0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, +	0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, +	0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, +	0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, +	0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, +	0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, +	0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, +	0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; + +static void desfunc(register unsigned long *block, +                    register unsigned long *keys) +{ +	register unsigned long fval, work, right, leftt; +	register int round; + +	leftt = block[0]; +	right = block[1]; +	work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; +	right ^= work; +	leftt ^= (work << 4); +	work = ((leftt >> 16) ^ right) & 0x0000ffffL; +	right ^= work; +	leftt ^= (work << 16); +	work = ((right >> 2) ^ leftt) & 0x33333333L; +	leftt ^= work; +	right ^= (work << 2); +	work = ((right >> 8) ^ leftt) & 0x00ff00ffL; +	leftt ^= work; +	right ^= (work << 8); +	right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; +	work = (leftt ^ right) & 0xaaaaaaaaL; +	leftt ^= work; +	right ^= work; +	leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; + +	for( round = 0; round < 8; round++ ) { +		work  = (right << 28) | (right >> 4); +		work ^= *keys++; +		fval  = SP7[ work		 & 0x3fL]; +		fval |= SP5[(work >>  8) & 0x3fL]; +		fval |= SP3[(work >> 16) & 0x3fL]; +		fval |= SP1[(work >> 24) & 0x3fL]; +		work  = right ^ *keys++; +		fval |= SP8[ work		 & 0x3fL]; +		fval |= SP6[(work >>  8) & 0x3fL]; +		fval |= SP4[(work >> 16) & 0x3fL]; +		fval |= SP2[(work >> 24) & 0x3fL]; +		leftt ^= fval; +		work  = (leftt << 28) | (leftt >> 4); +		work ^= *keys++; +		fval  = SP7[ work		 & 0x3fL]; +		fval |= SP5[(work >>  8) & 0x3fL]; +		fval |= SP3[(work >> 16) & 0x3fL]; +		fval |= SP1[(work >> 24) & 0x3fL]; +		work  = leftt ^ *keys++; +		fval |= SP8[ work		 & 0x3fL]; +		fval |= SP6[(work >>  8) & 0x3fL]; +		fval |= SP4[(work >> 16) & 0x3fL]; +		fval |= SP2[(work >> 24) & 0x3fL]; +		right ^= fval; +		} + +	right = (right << 31) | (right >> 1); +	work = (leftt ^ right) & 0xaaaaaaaaL; +	leftt ^= work; +	right ^= work; +	leftt = (leftt << 31) | (leftt >> 1); +	work = ((leftt >> 8) ^ right) & 0x00ff00ffL; +	right ^= work; +	leftt ^= (work << 8); +	work = ((leftt >> 2) ^ right) & 0x33333333L; +	right ^= work; +	leftt ^= (work << 2); +	work = ((right >> 16) ^ leftt) & 0x0000ffffL; +	leftt ^= work; +	right ^= (work << 16); +	work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; +	leftt ^= work; +	right ^= (work << 4); +	*block++ = right; +	*block = leftt; +	return; +	} + +/* Validation sets: + * + * Single-length key, single-length plaintext - + * Key	  : 0123 4567 89ab cdef + * Plain  : 0123 4567 89ab cde7 + * Cipher : c957 4425 6a5e d31d + * + * Double-length key, single-length plaintext - + * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Plain  : 0123 4567 89ab cde7 + * Cipher : 7f1d 0a77 826b 8aff + * + * Double-length key, double-length plaintext - + * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Plain  : 0123 4567 89ab cdef 0123 4567 89ab cdff + * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 + * + * Triple-length key, single-length plaintext - + * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Plain  : 0123 4567 89ab cde7 + * Cipher : de0b 7c06 ae5e 0ed5 + * + * Triple-length key, double-length plaintext - + * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Plain  : 0123 4567 89ab cdef 0123 4567 89ab cdff + * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 + * + * d3des V5.0a rwo 9208.07 18:44 Graven Imagery + **********************************************************************/ diff --git a/3rdParty/LibVNC/src/libvncserver/d3des.h b/3rdParty/LibVNC/src/libvncserver/d3des.h new file mode 100755 index 0000000..e3761ca --- /dev/null +++ b/3rdParty/LibVNC/src/libvncserver/d3des.h @@ -0,0 +1,56 @@ +#ifndef D3DES_H +#define D3DES_H + +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and + * triple-length support removed for use in VNC. + * + * These changes are: + *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* d3des.h - + * + *	Headers and defines for d3des.c + *	Graven Imagery, 1992. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge + *	(GEnie : OUTER; CIS : [71755,204]) + */ + +#define EN0	0	/* MODE == encrypt */ +#define DE1	1	/* MODE == decrypt */ + +extern void rfbDesKey(unsigned char *, int); +/*		      hexkey[8]     MODE + * Sets the internal key register according to the hexadecimal + * key contained in the 8 bytes of hexkey, according to the DES, + * for encryption or decryption according to MODE. + */ + +extern void rfbUseKey(unsigned long *); +/*		    cookedkey[32] + * Loads the internal key register with the data in cookedkey. + */ + +extern void rfbCPKey(unsigned long *); +/*		   cookedkey[32] + * Copies the contents of the internal key register into the storage + * located at &cookedkey[0]. + */ + +extern void rfbDes(unsigned char *, unsigned char *); +/*		    from[8]	      to[8] + * Encrypts/Decrypts (according to the key currently loaded in the + * internal key register) one block of eight bytes at address 'from' + * into the block at address 'to'.  They can be the same. + */ + +/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery + ********************************************************************/ + +#endif diff --git a/3rdParty/LibVNC/src/libvncserver/vncauth.c b/3rdParty/LibVNC/src/libvncserver/vncauth.c new file mode 100644 index 0000000..0b73531 --- /dev/null +++ b/3rdParty/LibVNC/src/libvncserver/vncauth.c @@ -0,0 +1,208 @@ +/* + *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved. + * + *  This is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This software is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, + *  USA. + */ + +/* + * vncauth.c - Functions for VNC password management and authentication. + */ + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#define _POSIX_SOURCE +#endif +#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <rfb/rfbproto.h> +#include "d3des.h" + +#include <string.h> +#include <math.h> + +#ifdef LIBVNCSERVER_HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#include <time.h> + +#ifdef WIN32 +#define srandom srand +#define random rand +#else +#include <sys/time.h> +#endif + + +/* libvncclient does not need this */ +#ifndef rfbEncryptBytes + +/* + * We use a fixed key to store passwords, since we assume that our local + * file system is secure but nonetheless don't want to store passwords + * as plaintext. + */ + +static unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; + + +/* + * Encrypt a password and store it in a file.  Returns 0 if successful, + * 1 if the file could not be written. + */ + +int +rfbEncryptAndStorePasswd(char *passwd, char *fname) +{ +    FILE *fp; +    unsigned int i; +    unsigned char encryptedPasswd[8]; + +    if ((fp = fopen(fname,"w")) == NULL) return 1; + +	/* windows security sux */ +#ifndef WIN32 +    fchmod(fileno(fp), S_IRUSR|S_IWUSR); +#endif + +    /* pad password with nulls */ + +    for (i = 0; i < 8; i++) { +	if (i < strlen(passwd)) { +	    encryptedPasswd[i] = passwd[i]; +	} else { +	    encryptedPasswd[i] = 0; +	} +    } + +    /* Do encryption in-place - this way we overwrite our copy of the plaintext +       password */ + +    rfbDesKey(fixedkey, EN0); +    rfbDes(encryptedPasswd, encryptedPasswd); + +    for (i = 0; i < 8; i++) { +	putc(encryptedPasswd[i], fp); +    } +   +    fclose(fp); +    return 0; +} + + +/* + * Decrypt a password from a file.  Returns a pointer to a newly allocated + * string containing the password or a null pointer if the password could + * not be retrieved for some reason. + */ + +char * +rfbDecryptPasswdFromFile(char *fname) +{ +    FILE *fp; +    int i, ch; +    unsigned char *passwd = (unsigned char *)malloc(9); + +    if ((fp = fopen(fname,"r")) == NULL) return NULL; + +    for (i = 0; i < 8; i++) { +	ch = getc(fp); +	if (ch == EOF) { +	    fclose(fp); +	    return NULL; +	} +	passwd[i] = ch; +    } + +    fclose(fp); + +    rfbDesKey(fixedkey, DE1); +    rfbDes(passwd, passwd); + +    passwd[8] = 0; + +    return (char *)passwd; +} + + +/* + * Generate CHALLENGESIZE random bytes for use in challenge-response + * authentication. + */ + +void +rfbRandomBytes(unsigned char *bytes) +{ +    int i; +    static rfbBool s_srandom_called = FALSE; + +    if (!s_srandom_called) { +	srandom((unsigned int)time(NULL) ^ (unsigned int)getpid()); +	s_srandom_called = TRUE; +    } + +    for (i = 0; i < CHALLENGESIZE; i++) { +	bytes[i] = (unsigned char)(random() & 255);     +    } +} + +#endif + +/* + * Encrypt CHALLENGESIZE bytes in memory using a password. + */ + +void +rfbEncryptBytes(unsigned char *bytes, char *passwd) +{ +    unsigned char key[8]; +    unsigned int i; + +    /* key is simply password padded with nulls */ + +    for (i = 0; i < 8; i++) { +	if (i < strlen(passwd)) { +	    key[i] = passwd[i]; +	} else { +	    key[i] = 0; +	} +    } + +    rfbDesKey(key, EN0); + +    for (i = 0; i < CHALLENGESIZE; i += 8) { +	rfbDes(bytes+i, bytes+i); +    } +} + +void +rfbEncryptBytes2(unsigned char *where, const int length, unsigned char *key) { +  int i, j; +  rfbDesKey(key, EN0); +  for (i = 0; i< 8; i++) +    where[i] ^= key[i]; +  rfbDes(where, where); +  for (i = 8; i < length; i += 8) { +    for (j = 0; j < 8; j++) +      where[i + j] ^= where[i + j - 8]; +      rfbDes(where + i, where + i); +  } +} + diff --git a/3rdParty/LibVNC/src/libvncserver/zywrletemplate.c b/3rdParty/LibVNC/src/libvncserver/zywrletemplate.c new file mode 100644 index 0000000..52b2b0b --- /dev/null +++ b/3rdParty/LibVNC/src/libvncserver/zywrletemplate.c @@ -0,0 +1,824 @@ + +/******************************************************************** + *                                                                  * + * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE.         * + *                                                                  * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     * + * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE.                * + * PLEASE READ THESE TERMS BEFORE DISTRIBUTING.                     * + *                                                                  * + * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006         * + * BY Hitachi Systems & Services, Ltd.                              * + * (Noriaki Yamazaki, Research & Developement Center)               *                                                                 * + *                                                                  * + ******************************************************************** +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Hitachi Systems & Services, Ltd. nor +the names of its contributors may be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************/ + +/* Change Log: +     V0.02 : 2008/02/04 : Fix mis encode/decode when width != scanline +	                     (Thanks Johannes Schindelin, author of LibVNC +						  Server/Client) +     V0.01 : 2007/02/06 : Initial release +*/ + +/* #define ZYWRLE_ENCODE */ +/* #define ZYWRLE_DECODE */ +#define ZYWRLE_QUANTIZE + +/* +[References] + PLHarr: +   Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy, "An Improved N-Bit to N-Bit Reversible Haar-Like Transform," Pacific Graphics 2004, October 2004, pp. 371-380. + EZW: +   Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet Coefficients, IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993). +*/ + + +/* Template Macro stuffs. */ +#undef ZYWRLE_ANALYZE +#undef ZYWRLE_SYNTHESIZE +#define ZYWRLE_ANALYZE __RFB_CONCAT3E(zywrleAnalyze,BPP,END_FIX) +#define ZYWRLE_SYNTHESIZE __RFB_CONCAT3E(zywrleSynthesize,BPP,END_FIX) + +#define ZYWRLE_RGBYUV __RFB_CONCAT3E(zywrleRGBYUV,BPP,END_FIX) +#define ZYWRLE_YUVRGB __RFB_CONCAT3E(zywrleYUVRGB,BPP,END_FIX) +#define ZYWRLE_YMASK __RFB_CONCAT2E(ZYWRLE_YMASK,BPP) +#define ZYWRLE_UVMASK __RFB_CONCAT2E(ZYWRLE_UVMASK,BPP) +#define ZYWRLE_LOAD_PIXEL __RFB_CONCAT2E(ZYWRLE_LOAD_PIXEL,BPP) +#define ZYWRLE_SAVE_PIXEL __RFB_CONCAT2E(ZYWRLE_SAVE_PIXEL,BPP) + +/* Packing/Unpacking pixel stuffs. +   Endian conversion stuffs. */ +#undef S_0 +#undef S_1 +#undef L_0 +#undef L_1 +#undef L_2 +#if ZYWRLE_ENDIAN == ENDIAN_BIG +#  define S_0	1 +#  define S_1	0 +#  define L_0	3 +#  define L_1	2 +#  define L_2	1 +#else +#  define S_0	0 +#  define S_1	1 +#  define L_0	0 +#  define L_1	1 +#  define L_2	2 +#endif + +/*   Load/Save pixel stuffs. */ +#define ZYWRLE_YMASK15  0xFFFFFFF8 +#define ZYWRLE_UVMASK15 0xFFFFFFF8 +#define ZYWRLE_LOAD_PIXEL15(pSrc,R,G,B) { \ +	R =  (((unsigned char*)pSrc)[S_1]<< 1)& 0xF8;	\ +	G = ((((unsigned char*)pSrc)[S_1]<< 6)|(((unsigned char*)pSrc)[S_0]>> 2))& 0xF8;	\ +	B =  (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8;	\ +} +#define ZYWRLE_SAVE_PIXEL15(pDst,R,G,B) { \ +	R &= 0xF8;	\ +	G &= 0xF8;	\ +	B &= 0xF8;	\ +	((unsigned char*)pDst)[S_1] = (unsigned char)( (R>>1)|(G>>6)       );	\ +	((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<2))& 0xFF);	\ +} +#define ZYWRLE_YMASK16  0xFFFFFFFC +#define ZYWRLE_UVMASK16 0xFFFFFFF8 +#define ZYWRLE_LOAD_PIXEL16(pSrc,R,G,B) { \ +	R =   ((unsigned char*)pSrc)[S_1]     & 0xF8;	\ +	G = ((((unsigned char*)pSrc)[S_1]<< 5)|(((unsigned char*)pSrc)[S_0]>> 3))& 0xFC;	\ +	B =  (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8;	\ +} +#define ZYWRLE_SAVE_PIXEL16(pDst,R,G,B) { \ +	R &= 0xF8;	\ +	G &= 0xFC;	\ +	B &= 0xF8;	\ +	((unsigned char*)pDst)[S_1] = (unsigned char)(  R    |(G>>5)       );	\ +	((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<3))& 0xFF);	\ +} +#define ZYWRLE_YMASK32  0xFFFFFFFF +#define ZYWRLE_UVMASK32 0xFFFFFFFF +#define ZYWRLE_LOAD_PIXEL32(pSrc,R,G,B) { \ +	R = ((unsigned char*)pSrc)[L_2];	\ +	G = ((unsigned char*)pSrc)[L_1];	\ +	B = ((unsigned char*)pSrc)[L_0];	\ +} +#define ZYWRLE_SAVE_PIXEL32(pDst,R,G,B) { \ +	((unsigned char*)pDst)[L_2] = (unsigned char)R;	\ +	((unsigned char*)pDst)[L_1] = (unsigned char)G;	\ +	((unsigned char*)pDst)[L_0] = (unsigned char)B;	\ +} + +#ifndef ZYWRLE_ONCE +#define ZYWRLE_ONCE + +#ifdef WIN32 +#define InlineX __inline +#else +#define InlineX inline +#endif + +#ifdef ZYWRLE_ENCODE +/* Tables for Coefficients filtering. */ +#  ifndef ZYWRLE_QUANTIZE +/* Type A:lower bit omitting of EZW style. */ +const static unsigned int zywrleParam[3][3]={ +	{0x0000F000,0x00000000,0x00000000}, +	{0x0000C000,0x00F0F0F0,0x00000000}, +	{0x0000C000,0x00C0C0C0,0x00F0F0F0}, +/*	{0x0000FF00,0x00000000,0x00000000}, +	{0x0000FF00,0x00FFFFFF,0x00000000}, +	{0x0000FF00,0x00FFFFFF,0x00FFFFFF}, */ +}; +#  else +/* Type B:Non liner quantization filter. */ +static const signed char zywrleConv[4][256]={ +{	/* bi=5, bo=5 r=0.0:PSNR=24.849 */ +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +}, +{	/* bi=5, bo=5 r=2.0:PSNR=74.031 */ +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 32, +	32, 32, 32, 32, 32, 32, 32, 32, +	32, 32, 32, 32, 32, 32, 32, 32, +	48, 48, 48, 48, 48, 48, 48, 48, +	48, 48, 48, 56, 56, 56, 56, 56, +	56, 56, 56, 56, 64, 64, 64, 64, +	64, 64, 64, 64, 72, 72, 72, 72, +	72, 72, 72, 72, 80, 80, 80, 80, +	80, 80, 88, 88, 88, 88, 88, 88, +	88, 88, 88, 88, 88, 88, 96, 96, +	96, 96, 96, 104, 104, 104, 104, 104, +	104, 104, 104, 104, 104, 112, 112, 112, +	112, 112, 112, 112, 112, 112, 120, 120, +	120, 120, 120, 120, 120, 120, 120, 120, +	0, -120, -120, -120, -120, -120, -120, -120, +	-120, -120, -120, -112, -112, -112, -112, -112, +	-112, -112, -112, -112, -104, -104, -104, -104, +	-104, -104, -104, -104, -104, -104, -96, -96, +	-96, -96, -96, -88, -88, -88, -88, -88, +	-88, -88, -88, -88, -88, -88, -88, -80, +	-80, -80, -80, -80, -80, -72, -72, -72, +	-72, -72, -72, -72, -72, -64, -64, -64, +	-64, -64, -64, -64, -64, -56, -56, -56, +	-56, -56, -56, -56, -56, -56, -48, -48, +	-48, -48, -48, -48, -48, -48, -48, -48, +	-48, -32, -32, -32, -32, -32, -32, -32, +	-32, -32, -32, -32, -32, -32, -32, -32, +	-32, -32, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +}, +{	/* bi=5, bo=4 r=2.0:PSNR=64.441 */ +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	48, 48, 48, 48, 48, 48, 48, 48, +	48, 48, 48, 48, 48, 48, 48, 48, +	48, 48, 48, 48, 48, 48, 48, 48, +	64, 64, 64, 64, 64, 64, 64, 64, +	64, 64, 64, 64, 64, 64, 64, 64, +	80, 80, 80, 80, 80, 80, 80, 80, +	80, 80, 80, 80, 80, 88, 88, 88, +	88, 88, 88, 88, 88, 88, 88, 88, +	104, 104, 104, 104, 104, 104, 104, 104, +	104, 104, 104, 112, 112, 112, 112, 112, +	112, 112, 112, 112, 120, 120, 120, 120, +	120, 120, 120, 120, 120, 120, 120, 120, +	0, -120, -120, -120, -120, -120, -120, -120, +	-120, -120, -120, -120, -120, -112, -112, -112, +	-112, -112, -112, -112, -112, -112, -104, -104, +	-104, -104, -104, -104, -104, -104, -104, -104, +	-104, -88, -88, -88, -88, -88, -88, -88, +	-88, -88, -88, -88, -80, -80, -80, -80, +	-80, -80, -80, -80, -80, -80, -80, -80, +	-80, -64, -64, -64, -64, -64, -64, -64, +	-64, -64, -64, -64, -64, -64, -64, -64, +	-64, -48, -48, -48, -48, -48, -48, -48, +	-48, -48, -48, -48, -48, -48, -48, -48, +	-48, -48, -48, -48, -48, -48, -48, -48, +	-48, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +}, +{	/* bi=5, bo=2 r=2.0:PSNR=43.175 */ +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	88, 88, 88, 88, 88, 88, 88, 88, +	88, 88, 88, 88, 88, 88, 88, 88, +	88, 88, 88, 88, 88, 88, 88, 88, +	88, 88, 88, 88, 88, 88, 88, 88, +	88, 88, 88, 88, 88, 88, 88, 88, +	88, 88, 88, 88, 88, 88, 88, 88, +	88, 88, 88, 88, 88, 88, 88, 88, +	88, 88, 88, 88, 88, 88, 88, 88, +	0, -88, -88, -88, -88, -88, -88, -88, +	-88, -88, -88, -88, -88, -88, -88, -88, +	-88, -88, -88, -88, -88, -88, -88, -88, +	-88, -88, -88, -88, -88, -88, -88, -88, +	-88, -88, -88, -88, -88, -88, -88, -88, +	-88, -88, -88, -88, -88, -88, -88, -88, +	-88, -88, -88, -88, -88, -88, -88, -88, +	-88, -88, -88, -88, -88, -88, -88, -88, +	-88, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, +} +}; +const static signed char* zywrleParam[3][3][3]={ +	{{zywrleConv[0],zywrleConv[2],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}}, +	{{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}}, +	{{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[2],zywrleConv[2],zywrleConv[2]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]}}, +}; +#  endif +#endif + +static InlineX void Harr(signed char* pX0, signed char* pX1) +{ +	/* Piecewise-Linear Harr(PLHarr) */ +	int X0 = (int)*pX0, X1 = (int)*pX1; +	int orgX0 = X0, orgX1 = X1; +	if ((X0 ^ X1) & 0x80) { +		/* differ sign */ +		X1 += X0; +		if (((X1^orgX1)&0x80)==0) { +			/* |X1| > |X0| */ +			X0 -= X1;	/* H = -B */ +		} +	} else { +		/* same sign */ +		X0 -= X1; +		if (((X0 ^ orgX0) & 0x80) == 0) { +			/* |X0| > |X1| */ +			X1 += X0;	/* L = A */ +		} +	} +	*pX0 = (signed char)X1; +	*pX1 = (signed char)X0; +} +/* + 1D-Wavelet transform. + + In coefficients array, the famous 'pyramid' decomposition is well used. + + 1D Model: +   |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0 +   |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1 + + But this method needs line buffer because H/L is different position from X0/X1. + So, I used 'interleave' decomposition instead of it. + + 1D Model: +   |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0 +   |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1 + + In this method, H/L and X0/X1 is always same position. + This lead us to more speed and less memory. + Of cause, the result of both method is quite same + because it's only difference that coefficient position. +*/ +static InlineX void WaveletLevel(int* data, int size, int l, int SkipPixel) +{ +	int s, ofs; +	signed char* pX0; +	signed char* end; + +	pX0 = (signed char*)data; +	s = (8<<l)*SkipPixel; +	end = pX0+(size>>(l+1))*s; +	s -= 2; +	ofs = (4<<l)*SkipPixel; +	while (pX0 < end) { +		Harr(pX0, pX0+ofs); +		pX0++; +		Harr(pX0, pX0+ofs); +		pX0++; +		Harr(pX0, pX0+ofs); +		pX0 += s; +	} +} +#define InvWaveletLevel(d,s,l,pix) WaveletLevel(d,s,l,pix) + +#ifdef ZYWRLE_ENCODE +#  ifndef ZYWRLE_QUANTIZE +/* Type A:lower bit omitting of EZW style. */ +static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l) +{ +	int r, s; +	int x, y; +	int* pH; +	const unsigned int* pM; + +	pM = &(zywrleParam[level-1][l]); +	s = 2<<l; +	for (r = 1; r < 4; r++) { +		pH   = pBuf; +		if (r & 0x01) +			pH +=  s>>1; +		if (r & 0x02) +			pH += (s>>1)*width; +		for (y = 0; y < height / s; y++) { +			for (x = 0; x < width / s; x++) { +				/* +				 these are same following code. +				     pH[x] = pH[x] / (~pM[x]+1) * (~pM[x]+1); +				     ( round pH[x] with pM[x] bit ) +				 '&' operator isn't 'round' but is 'floor'. +				 So, we must offset when pH[x] is negative. +				*/ +				if (((signed char*)pH)[0] & 0x80) +					((signed char*)pH)[0] += ~((signed char*)pM)[0]; +				if (((signed char*)pH)[1] & 0x80) +					((signed char*)pH)[1] += ~((signed char*)pM)[1]; +				if (((signed char*)pH)[2] & 0x80) +					((signed char*)pH)[2] += ~((signed char*)pM)[2]; +				*pH &= *pM; +				pH += s; +			} +			pH += (s-1)*width; +		} +	} +} +#  else +/* + Type B:Non liner quantization filter. + + Coefficients have Gaussian curve and smaller value which is + large part of coefficients isn't more important than larger value. + So, I use filter of Non liner quantize/dequantize table. + In general, Non liner quantize formula is explained as following. + +    y=f(x)   = sign(x)*round( ((abs(x)/(2^7))^ r   )* 2^(bo-1) )*2^(8-bo) +    x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi) + ( r:power coefficient  bi:effective MSB in input  bo:effective MSB in output ) + +   r < 1.0 : Smaller value is more important than larger value. +   r > 1.0 : Larger value is more important than smaller value. +   r = 1.0 : Liner quantization which is same with EZW style. + + r = 0.75 is famous non liner quantization used in MP3 audio codec. + In contrast to audio data, larger value is important in wavelet coefficients. + So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ). + + As compared with EZW style liner quantization, this filter tended to be + more sharp edge and be more compression rate but be more blocking noise and be less quality. + Especially, the surface of graphic objects has distinguishable noise in middle quality mode. + + We need only quantized-dequantized(filtered) value rather than quantized value itself + because all values are packed or palette-lized in later ZRLE section. + This lead us not to need to modify client decoder when we change + the filtering procedure in future. + Client only decodes coefficients given by encoder. +*/ +static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l) +{ +	int r, s; +	int x, y; +	int* pH; +	const signed char** pM; + +	pM = zywrleParam[level-1][l]; +	s = 2<<l; +	for (r = 1; r < 4; r++) { +		pH   = pBuf; +		if (r & 0x01) +			pH +=  s>>1; +		if (r & 0x02) +			pH += (s>>1)*width; +		for (y = 0; y < height / s; y++) { +			for (x = 0; x < width / s; x++) { +				((signed char*)pH)[0] = pM[0][((unsigned char*)pH)[0]]; +				((signed char*)pH)[1] = pM[1][((unsigned char*)pH)[1]]; +				((signed char*)pH)[2] = pM[2][((unsigned char*)pH)[2]]; +				pH += s; +			} +			pH += (s-1)*width; +		} +	} +} +#  endif + +static InlineX void Wavelet(int* pBuf, int width, int height, int level) +{ +	int l, s; +	int* pTop; +	int* pEnd; + +	for (l = 0; l < level; l++) { +		pTop = pBuf; +		pEnd = pBuf+height*width; +		s = width<<l; +		while (pTop < pEnd) { +			WaveletLevel(pTop, width, l, 1); +			pTop += s; +		} +		pTop = pBuf; +		pEnd = pBuf+width; +		s = 1<<l; +		while (pTop < pEnd) { +			WaveletLevel(pTop, height,l, width); +			pTop += s; +		} +		FilterWaveletSquare(pBuf, width, height, level, l); +	} +} +#endif +#ifdef ZYWRLE_DECODE +static InlineX void InvWavelet(int* pBuf, int width, int height, int level) +{ +	int l, s; +	int* pTop; +	int* pEnd; + +	for (l = level - 1; l >= 0; l--) { +		pTop = pBuf; +		pEnd = pBuf+width; +		s = 1<<l; +		while (pTop < pEnd) { +			InvWaveletLevel(pTop, height,l, width); +			pTop += s; +		} +		pTop = pBuf; +		pEnd = pBuf+height*width; +		s = width<<l; +		while (pTop < pEnd) { +			InvWaveletLevel(pTop, width, l, 1); +			pTop += s; +		} +	} +} +#endif + +/* Load/Save coefficients stuffs. + Coefficients manages as 24 bits little-endian pixel. */ +#define ZYWRLE_LOAD_COEFF(pSrc,R,G,B) { \ +	R = ((signed char*)pSrc)[2];	\ +	G = ((signed char*)pSrc)[1];	\ +	B = ((signed char*)pSrc)[0];	\ +} +#define ZYWRLE_SAVE_COEFF(pDst,R,G,B) { \ +	((signed char*)pDst)[2] = (signed char)R;	\ +	((signed char*)pDst)[1] = (signed char)G;	\ +	((signed char*)pDst)[0] = (signed char)B;	\ +} + +/* + RGB <=> YUV conversion stuffs. + YUV coversion is explained as following formula in strict meaning: +   Y =  0.299R + 0.587G + 0.114B (   0<=Y<=255) +   U = -0.169R - 0.331G + 0.500B (-128<=U<=127) +   V =  0.500R - 0.419G - 0.081B (-128<=V<=127) + + I use simple conversion RCT(reversible color transform) which is described + in JPEG-2000 specification. +   Y = (R + 2G + B)/4 (   0<=Y<=255) +   U = B-G (-256<=U<=255) +   V = R-G (-256<=V<=255) +*/ +#define ROUND(x) (((x)<0)?0:(((x)>255)?255:(x))) +	/* RCT is N-bit RGB to N-bit Y and N+1-bit UV. +	 For make Same N-bit, UV is lossy. +	 More exact PLHarr, we reduce to odd range(-127<=x<=127). */ +#define ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ymask,uvmask) { \ +	Y = (R+(G<<1)+B)>>2;	\ +	U =  B-G;	\ +	V =  R-G;	\ +	Y -= 128;	\ +	U >>= 1;	\ +	V >>= 1;	\ +	Y &= ymask;	\ +	U &= uvmask;	\ +	V &= uvmask;	\ +	if (Y == -128)	\ +		Y += (0xFFFFFFFF-ymask+1);	\ +	if (U == -128)	\ +		U += (0xFFFFFFFF-uvmask+1);	\ +	if (V == -128)	\ +		V += (0xFFFFFFFF-uvmask+1);	\ +} +#define ZYWRLE_YUVRGB1(R,G,B,Y,U,V) { \ +	Y += 128;	\ +	U <<= 1;	\ +	V <<= 1;	\ +	G = Y-((U+V)>>2);	\ +	B = U+G;	\ +	R = V+G;	\ +	G = ROUND(G);	\ +	B = ROUND(B);	\ +	R = ROUND(R);	\ +} + +/* + coefficient packing/unpacking stuffs. + Wavelet transform makes 4 sub coefficient image from 1 original image. + + model with pyramid decomposition: +   +------+------+ +   |      |      | +   |  L   |  Hx  | +   |      |      | +   +------+------+ +   |      |      | +   |  H   |  Hxy | +   |      |      | +   +------+------+ + + So, we must transfer each sub images individually in strict meaning. + But at least ZRLE meaning, following one decompositon image is same as + avobe individual sub image. I use this format. + (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L) +  for simplified procedure for any wavelet level.) + +   +------+------+ +   |      L      | +   +------+------+ +   |      Hx     | +   +------+------+ +   |      Hy     | +   +------+------+ +   |      Hxy    | +   +------+------+ +*/ +#define INC_PTR(data) \ +	data++;	\ +	if( data-pData >= (w+uw) ){	\ +		data += scanline-(w+uw);	\ +		pData = data;	\ +	} + +#define ZYWRLE_TRANSFER_COEFF(pBuf,data,r,w,h,scanline,level,TRANS)	\ +	pH = pBuf;	\ +	s = 2<<level;	\ +	if (r & 0x01)	\ +		pH +=  s>>1;	\ +	if (r & 0x02)	\ +		pH += (s>>1)*w;	\ +	pEnd = pH+h*w;	\ +	while (pH < pEnd) {	\ +		pLine = pH+w;	\ +		while (pH < pLine) {	\ +			TRANS	\ +			INC_PTR(data)	\ +			pH += s;	\ +		}	\ +		pH += (s-1)*w;	\ +	} + +#define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,scanline,level)	\ +	ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_COEFF(pH,R,G,B);ZYWRLE_SAVE_PIXEL(data,R,G,B);) + +#define ZYWRLE_UNPACK_COEFF(pBuf,data,r,width,height,scanline,level)	\ +	ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_PIXEL(data,R,G,B);ZYWRLE_SAVE_COEFF(pH,R,G,B);) + +#define ZYWRLE_SAVE_UNALIGN(data,TRANS)	\ +	pTop = pBuf+w*h;	\ +	pEnd = pBuf + (w+uw)*(h+uh);	\ +	while (pTop < pEnd) {	\ +		TRANS	\ +		INC_PTR(data)	\ +		pTop++;	\ +	} + +#define ZYWRLE_LOAD_UNALIGN(data,TRANS)	\ +	pTop = pBuf+w*h;	\ +	if (uw) {	\ +		pData=         data + w;	\ +		pEnd = (int*)(pData+ h*scanline);	\ +		while (pData < (PIXEL_T*)pEnd) {	\ +			pLine = (int*)(pData + uw);	\ +			while (pData < (PIXEL_T*)pLine) {	\ +				TRANS	\ +				pData++;	\ +				pTop++;	\ +			}	\ +			pData += scanline-uw;	\ +		}	\ +	}	\ +	if (uh) {	\ +		pData=         data +  h*scanline;	\ +		pEnd = (int*)(pData+ uh*scanline);	\ +		while (pData < (PIXEL_T*)pEnd) {	\ +			pLine = (int*)(pData + w);	\ +			while (pData < (PIXEL_T*)pLine) {	\ +				TRANS	\ +				pData++;	\ +				pTop++;	\ +			}	\ +			pData += scanline-w;	\ +		}	\ +	}	\ +	if (uw && uh) {	\ +		pData=         data + w+ h*scanline;	\ +		pEnd = (int*)(pData+   uh*scanline);	\ +		while (pData < (PIXEL_T*)pEnd) {	\ +			pLine = (int*)(pData + uw);	\ +			while (pData < (PIXEL_T*)pLine) {	\ +				TRANS	\ +				pData++;	\ +				pTop++;	\ +			}	\ +			pData += scanline-uw;	\ +		}	\ +	} + +static InlineX void zywrleCalcSize(int* pW, int* pH, int level) +{ +	*pW &= ~((1<<level)-1); +	*pH &= ~((1<<level)-1); +} + +#endif /* ZYWRLE_ONCE */ + +#ifndef CPIXEL +#ifdef ZYWRLE_ENCODE +static InlineX void ZYWRLE_RGBYUV(int* pBuf, PIXEL_T* data, int width, int height, int scanline) +{ +	int R, G, B; +	int Y, U, V; +	int* pLine; +	int* pEnd; +	pEnd = pBuf+height*width; +	while (pBuf < pEnd) { +		pLine = pBuf+width; +		while (pBuf < pLine) { +			ZYWRLE_LOAD_PIXEL(data,R,G,B); +			ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ZYWRLE_YMASK,ZYWRLE_UVMASK); +			ZYWRLE_SAVE_COEFF(pBuf,V,Y,U); +			pBuf++; +			data++; +		} +		data += scanline-width; +	} +} +#endif +#ifdef ZYWRLE_DECODE +static InlineX void ZYWRLE_YUVRGB(int* pBuf, PIXEL_T* data, int width, int height, int scanline) { +	int R, G, B; +	int Y, U, V; +	int* pLine; +	int* pEnd; +	pEnd = pBuf+height*width; +	while (pBuf < pEnd) { +		pLine = pBuf+width; +		while (pBuf < pLine) { +			ZYWRLE_LOAD_COEFF(pBuf,V,Y,U); +			ZYWRLE_YUVRGB1(R,G,B,Y,U,V); +			ZYWRLE_SAVE_PIXEL(data,R,G,B); +			pBuf++; +			data++; +		} +		data += scanline-width; +	} +} +#endif + +#ifdef ZYWRLE_ENCODE +PIXEL_T* ZYWRLE_ANALYZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf) { +	int l; +	int uw = w; +	int uh = h; +	int* pTop; +	int* pEnd; +	int* pLine; +	PIXEL_T* pData; +	int R, G, B; +	int s; +	int* pH; + +	zywrleCalcSize(&w, &h, level); +	if (w == 0 || h == 0) +		return NULL; +	uw -= w; +	uh -= h; + +	pData = dst; +	ZYWRLE_LOAD_UNALIGN(src,*(PIXEL_T*)pTop=*pData;) +	ZYWRLE_RGBYUV(pBuf, src, w, h, scanline); +	Wavelet(pBuf, w, h, level); +	for (l = 0; l < level; l++) { +		ZYWRLE_PACK_COEFF(pBuf, dst, 3, w, h, scanline, l); +		ZYWRLE_PACK_COEFF(pBuf, dst, 2, w, h, scanline, l); +		ZYWRLE_PACK_COEFF(pBuf, dst, 1, w, h, scanline, l); +		if (l == level - 1) { +			ZYWRLE_PACK_COEFF(pBuf, dst, 0, w, h, scanline, l); +		} +	} +	ZYWRLE_SAVE_UNALIGN(dst,*dst=*(PIXEL_T*)pTop;) +	return dst; +} +#endif +#ifdef ZYWRLE_DECODE +PIXEL_T* ZYWRLE_SYNTHESIZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf) +{ +	int l; +	int uw = w; +	int uh = h; +	int* pTop; +	int* pEnd; +	int* pLine; +	PIXEL_T* pData; +	int R, G, B; +	int s; +	int* pH; + +	zywrleCalcSize(&w, &h, level); +	if (w == 0 || h == 0) +		return NULL; +	uw -= w; +	uh -= h; + +	pData = src; +	for (l = 0; l < level; l++) { +		ZYWRLE_UNPACK_COEFF(pBuf, src, 3, w, h, scanline, l); +		ZYWRLE_UNPACK_COEFF(pBuf, src, 2, w, h, scanline, l); +		ZYWRLE_UNPACK_COEFF(pBuf, src, 1, w, h, scanline, l); +		if (l == level - 1) { +			ZYWRLE_UNPACK_COEFF(pBuf, src, 0, w, h, scanline, l); +		} +	} +	ZYWRLE_SAVE_UNALIGN(src,*(PIXEL_T*)pTop=*src;) +	InvWavelet(pBuf, w, h, level); +	ZYWRLE_YUVRGB(pBuf, dst, w, h, scanline); +	ZYWRLE_LOAD_UNALIGN(dst,*pData=*(PIXEL_T*)pTop;) +	return src; +} +#endif +#endif  /* CPIXEL */ + +#undef ZYWRLE_RGBYUV +#undef ZYWRLE_YUVRGB +#undef ZYWRLE_LOAD_PIXEL +#undef ZYWRLE_SAVE_PIXEL diff --git a/3rdParty/LibVNC/src/rfb/default8x16.h b/3rdParty/LibVNC/src/rfb/default8x16.h new file mode 100644 index 0000000..252f411 --- /dev/null +++ b/3rdParty/LibVNC/src/rfb/default8x16.h @@ -0,0 +1,261 @@ +static unsigned char default8x16FontData[4096+1]={ +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, +0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff, +0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00, +0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff, +0x00,0x00,0x1e,0x0e,0x1a,0x32,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00, +0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00, +0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00, +0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00, +0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00, +0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00, +0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00, +0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00, +0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xce,0xde,0xf6,0xe6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, +0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00, +0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, +0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, +0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0xe7,0xff,0xff,0xdb,0xc3,0xc3,0xc3,0xc3,0xc3,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00, +0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xff,0xdb,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x3c,0x66,0xc3,0xc3,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0xff,0xc3,0x86,0x0c,0x18,0x30,0x60,0xc1,0xc3,0xff,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00, +0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00, +0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00, +0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00, +0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00, +0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xe6,0xff,0xdb,0xdb,0xdb,0xdb,0xdb,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00, +0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00, +0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xc3,0x66,0x3c,0x18,0x3c,0x66,0xc3,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00, +0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, +0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00, +0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00, +0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x1b,0x7e,0xd8,0xdc,0x77,0x00,0x00,0x00,0x00, +0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00, +0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00, +0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x18,0x18,0x7e,0xc3,0xc0,0xc0,0xc0,0xc3,0x7e,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0x66,0x3c,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0xfc,0x66,0x66,0x7c,0x62,0x66,0x6f,0x66,0x66,0x66,0xf3,0x00,0x00,0x00,0x00, +0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00, +0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, +0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, +0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xce,0x9b,0x06,0x0c,0x1f,0x00,0x00, +0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x96,0x3e,0x06,0x06,0x00,0x00, +0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00, +0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, +0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa, +0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, +0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00, +0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, +0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00, +0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00, +0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x0e,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00, +0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static int default8x16FontMetaData[256*5+1]={ +0,8,16,0,0,16,8,16,0,0,32,8,16,0,0,48,8,16,0,0,64,8,16,0,0,80,8,16,0,0,96,8,16,0,0,112,8,16,0,0,128,8,16,0,0,144,8,16,0,0,160,8,16,0,0,176,8,16,0,0,192,8,16,0,0,208,8,16,0,0,224,8,16,0,0,240,8,16,0,0,256,8,16,0,0,272,8,16,0,0,288,8,16,0,0,304,8,16,0,0,320,8,16,0,0,336,8,16,0,0,352,8,16,0,0,368,8,16,0,0,384,8,16,0,0,400,8,16,0,0,416,8,16,0,0,432,8,16,0,0,448,8,16,0,0,464,8,16,0,0,480,8,16,0,0,496,8,16,0,0,512,8,16,0,0,528,8,16,0,0,544,8,16,0,0,560,8,16,0,0,576,8,16,0,0,592,8,16,0,0,608,8,16,0,0,624,8,16,0,0,640,8,16,0,0,656,8,16,0,0,672,8,16,0,0,688,8,16,0,0,704,8,16,0,0,720,8,16,0,0,736,8,16,0,0,752,8,16,0,0,768,8,16,0,0,784,8,16,0,0,800,8,16,0,0,816,8,16,0,0,832,8,16,0,0,848,8,16,0,0,864,8,16,0,0,880,8,16,0,0,896,8,16,0,0,912,8,16,0,0,928,8,16,0,0,944,8,16,0,0,960,8,16,0,0,976,8,16,0,0,992,8,16,0,0,1008,8,16,0,0,1024,8,16,0,0,1040,8,16,0,0,1056,8,16,0,0,1072,8,16,0,0,1088,8,16,0,0,1104,8,16,0,0,1120,8,16,0,0,1136,8,16,0,0,1152,8,16,0,0,1168,8,16,0,0,1184,8,16,0,0,1200,8,16,0,0,1216,8,16,0,0,1232,8,16,0,0,1248,8,16,0,0,1264,8,16,0,0,1280,8,16,0,0,1296,8,16,0,0,1312,8,16,0,0,1328,8,16,0,0,1344,8,16,0,0,1360,8,16,0,0,1376,8,16,0,0,1392,8,16,0,0,1408,8,16,0,0,1424,8,16,0,0,1440,8,16,0,0,1456,8,16,0,0,1472,8,16,0,0,1488,8,16,0,0,1504,8,16,0,0,1520,8,16,0,0,1536,8,16,0,0,1552,8,16,0,0,1568,8,16,0,0,1584,8,16,0,0,1600,8,16,0,0,1616,8,16,0,0,1632,8,16,0,0,1648,8,16,0,0,1664,8,16,0,0,1680,8,16,0,0,1696,8,16,0,0,1712,8,16,0,0,1728,8,16,0,0,1744,8,16,0,0,1760,8,16,0,0,1776,8,16,0,0,1792,8,16,0,0,1808,8,16,0,0,1824,8,16,0,0,1840,8,16,0,0,1856,8,16,0,0,1872,8,16,0,0,1888,8,16,0,0,1904,8,16,0,0,1920,8,16,0,0,1936,8,16,0,0,1952,8,16,0,0,1968,8,16,0,0,1984,8,16,0,0,2000,8,16,0,0,2016,8,16,0,0,2032,8,16,0,0,2048,8,16,0,0,2064,8,16,0,0,2080,8,16,0,0,2096,8,16,0,0,2112,8,16,0,0,2128,8,16,0,0,2144,8,16,0,0,2160,8,16,0,0,2176,8,16,0,0,2192,8,16,0,0,2208,8,16,0,0,2224,8,16,0,0,2240,8,16,0,0,2256,8,16,0,0,2272,8,16,0,0,2288,8,16,0,0,2304,8,16,0,0,2320,8,16,0,0,2336,8,16,0,0,2352,8,16,0,0,2368,8,16,0,0,2384,8,16,0,0,2400,8,16,0,0,2416,8,16,0,0,2432,8,16,0,0,2448,8,16,0,0,2464,8,16,0,0,2480,8,16,0,0,2496,8,16,0,0,2512,8,16,0,0,2528,8,16,0,0,2544,8,16,0,0,2560,8,16,0,0,2576,8,16,0,0,2592,8,16,0,0,2608,8,16,0,0,2624,8,16,0,0,2640,8,16,0,0,2656,8,16,0,0,2672,8,16,0,0,2688,8,16,0,0,2704,8,16,0,0,2720,8,16,0,0,2736,8,16,0,0,2752,8,16,0,0,2768,8,16,0,0,2784,8,16,0,0,2800,8,16,0,0,2816,8,16,0,0,2832,8,16,0,0,2848,8,16,0,0,2864,8,16,0,0,2880,8,16,0,0,2896,8,16,0,0,2912,8,16,0,0,2928,8,16,0,0,2944,8,16,0,0,2960,8,16,0,0,2976,8,16,0,0,2992,8,16,0,0,3008,8,16,0,0,3024,8,16,0,0,3040,8,16,0,0,3056,8,16,0,0,3072,8,16,0,0,3088,8,16,0,0,3104,8,16,0,0,3120,8,16,0,0,3136,8,16,0,0,3152,8,16,0,0,3168,8,16,0,0,3184,8,16,0,0,3200,8,16,0,0,3216,8,16,0,0,3232,8,16,0,0,3248,8,16,0,0,3264,8,16,0,0,3280,8,16,0,0,3296,8,16,0,0,3312,8,16,0,0,3328,8,16,0,0,3344,8,16,0,0,3360,8,16,0,0,3376,8,16,0,0,3392,8,16,0,0,3408,8,16,0,0,3424,8,16,0,0,3440,8,16,0,0,3456,8,16,0,0,3472,8,16,0,0,3488,8,16,0,0,3504,8,16,0,0,3520,8,16,0,0,3536,8,16,0,0,3552,8,16,0,0,3568,8,16,0,0,3584,8,16,0,0,3600,8,16,0,0,3616,8,16,0,0,3632,8,16,0,0,3648,8,16,0,0,3664,8,16,0,0,3680,8,16,0,0,3696,8,16,0,0,3712,8,16,0,0,3728,8,16,0,0,3744,8,16,0,0,3760,8,16,0,0,3776,8,16,0,0,3792,8,16,0,0,3808,8,16,0,0,3824,8,16,0,0,3840,8,16,0,0,3856,8,16,0,0,3872,8,16,0,0,3888,8,16,0,0,3904,8,16,0,0,3920,8,16,0,0,3936,8,16,0,0,3952,8,16,0,0,3968,8,16,0,0,3984,8,16,0,0,4000,8,16,0,0,4016,8,16,0,0,4032,8,16,0,0,4048,8,16,0,0,4064,8,16,0,0,4080,8,16,0,0,}; +static rfbFontData default8x16Font = { default8x16FontData, default8x16FontMetaData }; diff --git a/3rdParty/LibVNC/src/rfb/keysym.h b/3rdParty/LibVNC/src/rfb/keysym.h new file mode 100644 index 0000000..219f95b --- /dev/null +++ b/3rdParty/LibVNC/src/rfb/keysym.h @@ -0,0 +1,1638 @@ +#ifndef XK_0 + +/* $XConsortium: keysym.h,v 1.15 94/04/17 20:10:55 rws Exp $ */ + +/*********************************************************** + +Copyright (c) 1987  X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + +                        All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its  +documentation for any purpose and without fee is hereby granted,  +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in  +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission.   + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* default keysyms */ +#define XK_MISCELLANY +#define XK_XKB_KEYS +#define XK_LATIN1 +#define XK_LATIN2 +#define XK_LATIN3 +#define XK_LATIN4 +#define XK_GREEK + +/* $TOG: keysymdef.h /main/25 1997/06/21 10:54:51 kaleb $ */ + +/*********************************************************** +Copyright (c) 1987, 1994  X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts + +                        All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#define XK_VoidSymbol		0xFFFFFF	/* void symbol */ + +#ifdef XK_MISCELLANY +/* + * TTY Functions, cleverly chosen to map to ascii, for convenience of + * programming, but could have been arbitrary (at the cost of lookup + * tables in client code. + */ + +#define XK_BackSpace		0xFF08	/* back space, back char */ +#define XK_Tab			0xFF09 +#define XK_Linefeed		0xFF0A	/* Linefeed, LF */ +#define XK_Clear		0xFF0B +#define XK_Return		0xFF0D	/* Return, enter */ +#define XK_Pause		0xFF13	/* Pause, hold */ +#define XK_Scroll_Lock		0xFF14 +#define XK_Sys_Req		0xFF15 +#define XK_Escape		0xFF1B +#define XK_Delete		0xFFFF	/* Delete, rubout */ + + + +/* International & multi-key character composition */ + +#define XK_Multi_key		0xFF20  /* Multi-key character compose */ +#define XK_SingleCandidate	0xFF3C +#define XK_MultipleCandidate	0xFF3D +#define XK_PreviousCandidate	0xFF3E + +/* Japanese keyboard support */ + +#define XK_Kanji		0xFF21	/* Kanji, Kanji convert */ +#define XK_Muhenkan		0xFF22  /* Cancel Conversion */ +#define XK_Henkan_Mode		0xFF23  /* Start/Stop Conversion */ +#define XK_Henkan		0xFF23  /* Alias for Henkan_Mode */ +#define XK_Romaji		0xFF24  /* to Romaji */ +#define XK_Hiragana		0xFF25  /* to Hiragana */ +#define XK_Katakana		0xFF26  /* to Katakana */ +#define XK_Hiragana_Katakana	0xFF27  /* Hiragana/Katakana toggle */ +#define XK_Zenkaku		0xFF28  /* to Zenkaku */ +#define XK_Hankaku		0xFF29  /* to Hankaku */ +#define XK_Zenkaku_Hankaku	0xFF2A  /* Zenkaku/Hankaku toggle */ +#define XK_Touroku		0xFF2B  /* Add to Dictionary */ +#define XK_Massyo		0xFF2C  /* Delete from Dictionary */ +#define XK_Kana_Lock		0xFF2D  /* Kana Lock */ +#define XK_Kana_Shift		0xFF2E  /* Kana Shift */ +#define XK_Eisu_Shift		0xFF2F  /* Alphanumeric Shift */ +#define XK_Eisu_toggle		0xFF30  /* Alphanumeric toggle */ +#define XK_Zen_Koho		0xFF3D	/* Multiple/All Candidate(s) */ +#define XK_Mae_Koho		0xFF3E	/* Previous Candidate */ + +/* 0xFF31 thru 0xFF3F are under XK_KOREAN */ + +/* Cursor control & motion */ + +#define XK_Home			0xFF50 +#define XK_Left			0xFF51	/* Move left, left arrow */ +#define XK_Up			0xFF52	/* Move up, up arrow */ +#define XK_Right		0xFF53	/* Move right, right arrow */ +#define XK_Down			0xFF54	/* Move down, down arrow */ +#define XK_Prior		0xFF55	/* Prior, previous */ +#define XK_Page_Up		0xFF55 +#define XK_Next			0xFF56	/* Next */ +#define XK_Page_Down		0xFF56 +#define XK_End			0xFF57	/* EOL */ +#define XK_Begin		0xFF58	/* BOL */ + + +/* Misc Functions */ + +#define XK_Select		0xFF60	/* Select, mark */ +#define XK_Print		0xFF61 +#define XK_Execute		0xFF62	/* Execute, run, do */ +#define XK_Insert		0xFF63	/* Insert, insert here */ +#define XK_Undo			0xFF65	/* Undo, oops */ +#define XK_Redo			0xFF66	/* redo, again */ +#define XK_Menu			0xFF67 +#define XK_Find			0xFF68	/* Find, search */ +#define XK_Cancel		0xFF69	/* Cancel, stop, abort, exit */ +#define XK_Help			0xFF6A	/* Help */ +#define XK_Break		0xFF6B +#define XK_Mode_switch		0xFF7E	/* Character set switch */ +#define XK_script_switch        0xFF7E  /* Alias for mode_switch */ +#define XK_Num_Lock		0xFF7F + +/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ + +#define XK_KP_Space		0xFF80	/* space */ +#define XK_KP_Tab		0xFF89 +#define XK_KP_Enter		0xFF8D	/* enter */ +#define XK_KP_F1		0xFF91	/* PF1, KP_A, ... */ +#define XK_KP_F2		0xFF92 +#define XK_KP_F3		0xFF93 +#define XK_KP_F4		0xFF94 +#define XK_KP_Home		0xFF95 +#define XK_KP_Left		0xFF96 +#define XK_KP_Up		0xFF97 +#define XK_KP_Right		0xFF98 +#define XK_KP_Down		0xFF99 +#define XK_KP_Prior		0xFF9A +#define XK_KP_Page_Up		0xFF9A +#define XK_KP_Next		0xFF9B +#define XK_KP_Page_Down		0xFF9B +#define XK_KP_End		0xFF9C +#define XK_KP_Begin		0xFF9D +#define XK_KP_Insert		0xFF9E +#define XK_KP_Delete		0xFF9F +#define XK_KP_Equal		0xFFBD	/* equals */ +#define XK_KP_Multiply		0xFFAA +#define XK_KP_Add		0xFFAB +#define XK_KP_Separator		0xFFAC	/* separator, often comma */ +#define XK_KP_Subtract		0xFFAD +#define XK_KP_Decimal		0xFFAE +#define XK_KP_Divide		0xFFAF + +#define XK_KP_0			0xFFB0 +#define XK_KP_1			0xFFB1 +#define XK_KP_2			0xFFB2 +#define XK_KP_3			0xFFB3 +#define XK_KP_4			0xFFB4 +#define XK_KP_5			0xFFB5 +#define XK_KP_6			0xFFB6 +#define XK_KP_7			0xFFB7 +#define XK_KP_8			0xFFB8 +#define XK_KP_9			0xFFB9 + + + +/* + * Auxilliary Functions; note the duplicate definitions for left and right + * function keys;  Sun keyboards and a few other manufactures have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + +#define XK_F1			0xFFBE +#define XK_F2			0xFFBF +#define XK_F3			0xFFC0 +#define XK_F4			0xFFC1 +#define XK_F5			0xFFC2 +#define XK_F6			0xFFC3 +#define XK_F7			0xFFC4 +#define XK_F8			0xFFC5 +#define XK_F9			0xFFC6 +#define XK_F10			0xFFC7 +#define XK_F11			0xFFC8 +#define XK_L1			0xFFC8 +#define XK_F12			0xFFC9 +#define XK_L2			0xFFC9 +#define XK_F13			0xFFCA +#define XK_L3			0xFFCA +#define XK_F14			0xFFCB +#define XK_L4			0xFFCB +#define XK_F15			0xFFCC +#define XK_L5			0xFFCC +#define XK_F16			0xFFCD +#define XK_L6			0xFFCD +#define XK_F17			0xFFCE +#define XK_L7			0xFFCE +#define XK_F18			0xFFCF +#define XK_L8			0xFFCF +#define XK_F19			0xFFD0 +#define XK_L9			0xFFD0 +#define XK_F20			0xFFD1 +#define XK_L10			0xFFD1 +#define XK_F21			0xFFD2 +#define XK_R1			0xFFD2 +#define XK_F22			0xFFD3 +#define XK_R2			0xFFD3 +#define XK_F23			0xFFD4 +#define XK_R3			0xFFD4 +#define XK_F24			0xFFD5 +#define XK_R4			0xFFD5 +#define XK_F25			0xFFD6 +#define XK_R5			0xFFD6 +#define XK_F26			0xFFD7 +#define XK_R6			0xFFD7 +#define XK_F27			0xFFD8 +#define XK_R7			0xFFD8 +#define XK_F28			0xFFD9 +#define XK_R8			0xFFD9 +#define XK_F29			0xFFDA +#define XK_R9			0xFFDA +#define XK_F30			0xFFDB +#define XK_R10			0xFFDB +#define XK_F31			0xFFDC +#define XK_R11			0xFFDC +#define XK_F32			0xFFDD +#define XK_R12			0xFFDD +#define XK_F33			0xFFDE +#define XK_R13			0xFFDE +#define XK_F34			0xFFDF +#define XK_R14			0xFFDF +#define XK_F35			0xFFE0 +#define XK_R15			0xFFE0 + +/* Modifiers */ + +#define XK_Shift_L		0xFFE1	/* Left shift */ +#define XK_Shift_R		0xFFE2	/* Right shift */ +#define XK_Control_L		0xFFE3	/* Left control */ +#define XK_Control_R		0xFFE4	/* Right control */ +#define XK_Caps_Lock		0xFFE5	/* Caps lock */ +#define XK_Shift_Lock		0xFFE6	/* Shift lock */ + +#define XK_Meta_L		0xFFE7	/* Left meta */ +#define XK_Meta_R		0xFFE8	/* Right meta */ +#define XK_Alt_L		0xFFE9	/* Left alt */ +#define XK_Alt_R		0xFFEA	/* Right alt */ +#define XK_Super_L		0xFFEB	/* Left super */ +#define XK_Super_R		0xFFEC	/* Right super */ +#define XK_Hyper_L		0xFFED	/* Left hyper */ +#define XK_Hyper_R		0xFFEE	/* Right hyper */ +#endif /* XK_MISCELLANY */ + +/* + * ISO 9995 Function and Modifier Keys + * Byte 3 = 0xFE + */ + +#ifdef XK_XKB_KEYS +#define	XK_ISO_Lock					0xFE01 +#define	XK_ISO_Level2_Latch				0xFE02 +#define	XK_ISO_Level3_Shift				0xFE03 +#define	XK_ISO_Level3_Latch				0xFE04 +#define	XK_ISO_Level3_Lock				0xFE05 +#define	XK_ISO_Group_Shift		0xFF7E	/* Alias for mode_switch */ +#define	XK_ISO_Group_Latch				0xFE06 +#define	XK_ISO_Group_Lock				0xFE07 +#define	XK_ISO_Next_Group				0xFE08 +#define	XK_ISO_Next_Group_Lock				0xFE09 +#define	XK_ISO_Prev_Group				0xFE0A +#define	XK_ISO_Prev_Group_Lock				0xFE0B +#define	XK_ISO_First_Group				0xFE0C +#define	XK_ISO_First_Group_Lock				0xFE0D +#define	XK_ISO_Last_Group				0xFE0E +#define	XK_ISO_Last_Group_Lock				0xFE0F + +#define	XK_ISO_Left_Tab					0xFE20 +#define	XK_ISO_Move_Line_Up				0xFE21 +#define	XK_ISO_Move_Line_Down				0xFE22 +#define	XK_ISO_Partial_Line_Up				0xFE23 +#define	XK_ISO_Partial_Line_Down			0xFE24 +#define	XK_ISO_Partial_Space_Left			0xFE25 +#define	XK_ISO_Partial_Space_Right			0xFE26 +#define	XK_ISO_Set_Margin_Left				0xFE27 +#define	XK_ISO_Set_Margin_Right				0xFE28 +#define	XK_ISO_Release_Margin_Left			0xFE29 +#define	XK_ISO_Release_Margin_Right			0xFE2A +#define	XK_ISO_Release_Both_Margins			0xFE2B +#define	XK_ISO_Fast_Cursor_Left				0xFE2C +#define	XK_ISO_Fast_Cursor_Right			0xFE2D +#define	XK_ISO_Fast_Cursor_Up				0xFE2E +#define	XK_ISO_Fast_Cursor_Down				0xFE2F +#define	XK_ISO_Continuous_Underline			0xFE30 +#define	XK_ISO_Discontinuous_Underline			0xFE31 +#define	XK_ISO_Emphasize				0xFE32 +#define	XK_ISO_Center_Object				0xFE33 +#define	XK_ISO_Enter					0xFE34 + +#define	XK_dead_grave					0xFE50 +#define	XK_dead_acute					0xFE51 +#define	XK_dead_circumflex				0xFE52 +#define	XK_dead_tilde					0xFE53 +#define	XK_dead_macron					0xFE54 +#define	XK_dead_breve					0xFE55 +#define	XK_dead_abovedot				0xFE56 +#define	XK_dead_diaeresis				0xFE57 +#define	XK_dead_abovering				0xFE58 +#define	XK_dead_doubleacute				0xFE59 +#define	XK_dead_caron					0xFE5A +#define	XK_dead_cedilla					0xFE5B +#define	XK_dead_ogonek					0xFE5C +#define	XK_dead_iota					0xFE5D +#define	XK_dead_voiced_sound				0xFE5E +#define	XK_dead_semivoiced_sound			0xFE5F +#define	XK_dead_belowdot				0xFE60 + +#define	XK_First_Virtual_Screen				0xFED0 +#define	XK_Prev_Virtual_Screen				0xFED1 +#define	XK_Next_Virtual_Screen				0xFED2 +#define	XK_Last_Virtual_Screen				0xFED4 +#define	XK_Terminate_Server				0xFED5 + +#define	XK_AccessX_Enable				0xFE70 +#define	XK_AccessX_Feedback_Enable			0xFE71 +#define	XK_RepeatKeys_Enable				0xFE72 +#define	XK_SlowKeys_Enable				0xFE73 +#define	XK_BounceKeys_Enable				0xFE74 +#define	XK_StickyKeys_Enable				0xFE75 +#define	XK_MouseKeys_Enable				0xFE76 +#define	XK_MouseKeys_Accel_Enable			0xFE77 +#define	XK_Overlay1_Enable				0xFE78 +#define	XK_Overlay2_Enable				0xFE79 +#define	XK_AudibleBell_Enable				0xFE7A + +#define	XK_Pointer_Left					0xFEE0 +#define	XK_Pointer_Right				0xFEE1 +#define	XK_Pointer_Up					0xFEE2 +#define	XK_Pointer_Down					0xFEE3 +#define	XK_Pointer_UpLeft				0xFEE4 +#define	XK_Pointer_UpRight				0xFEE5 +#define	XK_Pointer_DownLeft				0xFEE6 +#define	XK_Pointer_DownRight				0xFEE7 +#define	XK_Pointer_Button_Dflt				0xFEE8 +#define	XK_Pointer_Button1				0xFEE9 +#define	XK_Pointer_Button2				0xFEEA +#define	XK_Pointer_Button3				0xFEEB +#define	XK_Pointer_Button4				0xFEEC +#define	XK_Pointer_Button5				0xFEED +#define	XK_Pointer_DblClick_Dflt			0xFEEE +#define	XK_Pointer_DblClick1				0xFEEF +#define	XK_Pointer_DblClick2				0xFEF0 +#define	XK_Pointer_DblClick3				0xFEF1 +#define	XK_Pointer_DblClick4				0xFEF2 +#define	XK_Pointer_DblClick5				0xFEF3 +#define	XK_Pointer_Drag_Dflt				0xFEF4 +#define	XK_Pointer_Drag1				0xFEF5 +#define	XK_Pointer_Drag2				0xFEF6 +#define	XK_Pointer_Drag3				0xFEF7 +#define	XK_Pointer_Drag4				0xFEF8 +#define	XK_Pointer_Drag5				0xFEFD + +#define	XK_Pointer_EnableKeys				0xFEF9 +#define	XK_Pointer_Accelerate				0xFEFA +#define	XK_Pointer_DfltBtnNext				0xFEFB +#define	XK_Pointer_DfltBtnPrev				0xFEFC + +#endif + +/* + * 3270 Terminal Keys + * Byte 3 = 0xFD + */ + +#ifdef XK_3270 +#define XK_3270_Duplicate      0xFD01 +#define XK_3270_FieldMark      0xFD02 +#define XK_3270_Right2         0xFD03 +#define XK_3270_Left2          0xFD04 +#define XK_3270_BackTab        0xFD05 +#define XK_3270_EraseEOF       0xFD06 +#define XK_3270_EraseInput     0xFD07 +#define XK_3270_Reset          0xFD08 +#define XK_3270_Quit           0xFD09 +#define XK_3270_PA1            0xFD0A +#define XK_3270_PA2            0xFD0B +#define XK_3270_PA3            0xFD0C +#define XK_3270_Test           0xFD0D +#define XK_3270_Attn           0xFD0E +#define XK_3270_CursorBlink    0xFD0F +#define XK_3270_AltCursor      0xFD10 +#define XK_3270_KeyClick       0xFD11 +#define XK_3270_Jump           0xFD12 +#define XK_3270_Ident          0xFD13 +#define XK_3270_Rule           0xFD14 +#define XK_3270_Copy           0xFD15 +#define XK_3270_Play           0xFD16 +#define XK_3270_Setup          0xFD17 +#define XK_3270_Record         0xFD18 +#define XK_3270_ChangeScreen   0xFD19 +#define XK_3270_DeleteWord     0xFD1A +#define XK_3270_ExSelect       0xFD1B +#define XK_3270_CursorSelect   0xFD1C +#define XK_3270_PrintScreen    0xFD1D +#define XK_3270_Enter          0xFD1E +#endif + +/* + *  Latin 1 + *  Byte 3 = 0 + */ +#ifdef XK_LATIN1 +#define XK_space               0x020 +#define XK_exclam              0x021 +#define XK_quotedbl            0x022 +#define XK_numbersign          0x023 +#define XK_dollar              0x024 +#define XK_percent             0x025 +#define XK_ampersand           0x026 +#define XK_apostrophe          0x027 +#define XK_quoteright          0x027	/* deprecated */ +#define XK_parenleft           0x028 +#define XK_parenright          0x029 +#define XK_asterisk            0x02a +#define XK_plus                0x02b +#define XK_comma               0x02c +#define XK_minus               0x02d +#define XK_period              0x02e +#define XK_slash               0x02f +#define XK_0                   0x030 +#define XK_1                   0x031 +#define XK_2                   0x032 +#define XK_3                   0x033 +#define XK_4                   0x034 +#define XK_5                   0x035 +#define XK_6                   0x036 +#define XK_7                   0x037 +#define XK_8                   0x038 +#define XK_9                   0x039 +#define XK_colon               0x03a +#define XK_semicolon           0x03b +#define XK_less                0x03c +#define XK_equal               0x03d +#define XK_greater             0x03e +#define XK_question            0x03f +#define XK_at                  0x040 +#define XK_A                   0x041 +#define XK_B                   0x042 +#define XK_C                   0x043 +#define XK_D                   0x044 +#define XK_E                   0x045 +#define XK_F                   0x046 +#define XK_G                   0x047 +#define XK_H                   0x048 +#define XK_I                   0x049 +#define XK_J                   0x04a +#define XK_K                   0x04b +#define XK_L                   0x04c +#define XK_M                   0x04d +#define XK_N                   0x04e +#define XK_O                   0x04f +#define XK_P                   0x050 +#define XK_Q                   0x051 +#define XK_R                   0x052 +#define XK_S                   0x053 +#define XK_T                   0x054 +#define XK_U                   0x055 +#define XK_V                   0x056 +#define XK_W                   0x057 +#define XK_X                   0x058 +#define XK_Y                   0x059 +#define XK_Z                   0x05a +#define XK_bracketleft         0x05b +#define XK_backslash           0x05c +#define XK_bracketright        0x05d +#define XK_asciicircum         0x05e +#define XK_underscore          0x05f +#define XK_grave               0x060 +#define XK_quoteleft           0x060	/* deprecated */ +#define XK_a                   0x061 +#define XK_b                   0x062 +#define XK_c                   0x063 +#define XK_d                   0x064 +#define XK_e                   0x065 +#define XK_f                   0x066 +#define XK_g                   0x067 +#define XK_h                   0x068 +#define XK_i                   0x069 +#define XK_j                   0x06a +#define XK_k                   0x06b +#define XK_l                   0x06c +#define XK_m                   0x06d +#define XK_n                   0x06e +#define XK_o                   0x06f +#define XK_p                   0x070 +#define XK_q                   0x071 +#define XK_r                   0x072 +#define XK_s                   0x073 +#define XK_t                   0x074 +#define XK_u                   0x075 +#define XK_v                   0x076 +#define XK_w                   0x077 +#define XK_x                   0x078 +#define XK_y                   0x079 +#define XK_z                   0x07a +#define XK_braceleft           0x07b +#define XK_bar                 0x07c +#define XK_braceright          0x07d +#define XK_asciitilde          0x07e + +#define XK_nobreakspace        0x0a0 +#define XK_exclamdown          0x0a1 +#define XK_cent        	       0x0a2 +#define XK_sterling            0x0a3 +#define XK_currency            0x0a4 +#define XK_yen                 0x0a5 +#define XK_brokenbar           0x0a6 +#define XK_section             0x0a7 +#define XK_diaeresis           0x0a8 +#define XK_copyright           0x0a9 +#define XK_ordfeminine         0x0aa +#define XK_guillemotleft       0x0ab	/* left angle quotation mark */ +#define XK_notsign             0x0ac +#define XK_hyphen              0x0ad +#define XK_registered          0x0ae +#define XK_macron              0x0af +#define XK_degree              0x0b0 +#define XK_plusminus           0x0b1 +#define XK_twosuperior         0x0b2 +#define XK_threesuperior       0x0b3 +#define XK_acute               0x0b4 +#define XK_mu                  0x0b5 +#define XK_paragraph           0x0b6 +#define XK_periodcentered      0x0b7 +#define XK_cedilla             0x0b8 +#define XK_onesuperior         0x0b9 +#define XK_masculine           0x0ba +#define XK_guillemotright      0x0bb	/* right angle quotation mark */ +#define XK_onequarter          0x0bc +#define XK_onehalf             0x0bd +#define XK_threequarters       0x0be +#define XK_questiondown        0x0bf +#define XK_Agrave              0x0c0 +#define XK_Aacute              0x0c1 +#define XK_Acircumflex         0x0c2 +#define XK_Atilde              0x0c3 +#define XK_Adiaeresis          0x0c4 +#define XK_Aring               0x0c5 +#define XK_AE                  0x0c6 +#define XK_Ccedilla            0x0c7 +#define XK_Egrave              0x0c8 +#define XK_Eacute              0x0c9 +#define XK_Ecircumflex         0x0ca +#define XK_Ediaeresis          0x0cb +#define XK_Igrave              0x0cc +#define XK_Iacute              0x0cd +#define XK_Icircumflex         0x0ce +#define XK_Idiaeresis          0x0cf +#define XK_ETH                 0x0d0 +#define XK_Eth                 0x0d0	/* deprecated */ +#define XK_Ntilde              0x0d1 +#define XK_Ograve              0x0d2 +#define XK_Oacute              0x0d3 +#define XK_Ocircumflex         0x0d4 +#define XK_Otilde              0x0d5 +#define XK_Odiaeresis          0x0d6 +#define XK_multiply            0x0d7 +#define XK_Ooblique            0x0d8 +#define XK_Ugrave              0x0d9 +#define XK_Uacute              0x0da +#define XK_Ucircumflex         0x0db +#define XK_Udiaeresis          0x0dc +#define XK_Yacute              0x0dd +#define XK_THORN               0x0de +#define XK_Thorn               0x0de	/* deprecated */ +#define XK_ssharp              0x0df +#define XK_agrave              0x0e0 +#define XK_aacute              0x0e1 +#define XK_acircumflex         0x0e2 +#define XK_atilde              0x0e3 +#define XK_adiaeresis          0x0e4 +#define XK_aring               0x0e5 +#define XK_ae                  0x0e6 +#define XK_ccedilla            0x0e7 +#define XK_egrave              0x0e8 +#define XK_eacute              0x0e9 +#define XK_ecircumflex         0x0ea +#define XK_ediaeresis          0x0eb +#define XK_igrave              0x0ec +#define XK_iacute              0x0ed +#define XK_icircumflex         0x0ee +#define XK_idiaeresis          0x0ef +#define XK_eth                 0x0f0 +#define XK_ntilde              0x0f1 +#define XK_ograve              0x0f2 +#define XK_oacute              0x0f3 +#define XK_ocircumflex         0x0f4 +#define XK_otilde              0x0f5 +#define XK_odiaeresis          0x0f6 +#define XK_division            0x0f7 +#define XK_oslash              0x0f8 +#define XK_ugrave              0x0f9 +#define XK_uacute              0x0fa +#define XK_ucircumflex         0x0fb +#define XK_udiaeresis          0x0fc +#define XK_yacute              0x0fd +#define XK_thorn               0x0fe +#define XK_ydiaeresis          0x0ff +#endif /* XK_LATIN1 */ + +/* + *   Latin 2 + *   Byte 3 = 1 + */ + +#ifdef XK_LATIN2 +#define XK_Aogonek             0x1a1 +#define XK_breve               0x1a2 +#define XK_Lstroke             0x1a3 +#define XK_Lcaron              0x1a5 +#define XK_Sacute              0x1a6 +#define XK_Scaron              0x1a9 +#define XK_Scedilla            0x1aa +#define XK_Tcaron              0x1ab +#define XK_Zacute              0x1ac +#define XK_Zcaron              0x1ae +#define XK_Zabovedot           0x1af +#define XK_aogonek             0x1b1 +#define XK_ogonek              0x1b2 +#define XK_lstroke             0x1b3 +#define XK_lcaron              0x1b5 +#define XK_sacute              0x1b6 +#define XK_caron               0x1b7 +#define XK_scaron              0x1b9 +#define XK_scedilla            0x1ba +#define XK_tcaron              0x1bb +#define XK_zacute              0x1bc +#define XK_doubleacute         0x1bd +#define XK_zcaron              0x1be +#define XK_zabovedot           0x1bf +#define XK_Racute              0x1c0 +#define XK_Abreve              0x1c3 +#define XK_Lacute              0x1c5 +#define XK_Cacute              0x1c6 +#define XK_Ccaron              0x1c8 +#define XK_Eogonek             0x1ca +#define XK_Ecaron              0x1cc +#define XK_Dcaron              0x1cf +#define XK_Dstroke             0x1d0 +#define XK_Nacute              0x1d1 +#define XK_Ncaron              0x1d2 +#define XK_Odoubleacute        0x1d5 +#define XK_Rcaron              0x1d8 +#define XK_Uring               0x1d9 +#define XK_Udoubleacute        0x1db +#define XK_Tcedilla            0x1de +#define XK_racute              0x1e0 +#define XK_abreve              0x1e3 +#define XK_lacute              0x1e5 +#define XK_cacute              0x1e6 +#define XK_ccaron              0x1e8 +#define XK_eogonek             0x1ea +#define XK_ecaron              0x1ec +#define XK_dcaron              0x1ef +#define XK_dstroke             0x1f0 +#define XK_nacute              0x1f1 +#define XK_ncaron              0x1f2 +#define XK_odoubleacute        0x1f5 +#define XK_udoubleacute        0x1fb +#define XK_rcaron              0x1f8 +#define XK_uring               0x1f9 +#define XK_tcedilla            0x1fe +#define XK_abovedot            0x1ff +#endif /* XK_LATIN2 */ + +/* + *   Latin 3 + *   Byte 3 = 2 + */ + +#ifdef XK_LATIN3 +#define XK_Hstroke             0x2a1 +#define XK_Hcircumflex         0x2a6 +#define XK_Iabovedot           0x2a9 +#define XK_Gbreve              0x2ab +#define XK_Jcircumflex         0x2ac +#define XK_hstroke             0x2b1 +#define XK_hcircumflex         0x2b6 +#define XK_idotless            0x2b9 +#define XK_gbreve              0x2bb +#define XK_jcircumflex         0x2bc +#define XK_Cabovedot           0x2c5 +#define XK_Ccircumflex         0x2c6 +#define XK_Gabovedot           0x2d5 +#define XK_Gcircumflex         0x2d8 +#define XK_Ubreve              0x2dd +#define XK_Scircumflex         0x2de +#define XK_cabovedot           0x2e5 +#define XK_ccircumflex         0x2e6 +#define XK_gabovedot           0x2f5 +#define XK_gcircumflex         0x2f8 +#define XK_ubreve              0x2fd +#define XK_scircumflex         0x2fe +#endif /* XK_LATIN3 */ + + +/* + *   Latin 4 + *   Byte 3 = 3 + */ + +#ifdef XK_LATIN4 +#define XK_kra                 0x3a2 +#define XK_kappa               0x3a2	/* deprecated */ +#define XK_Rcedilla            0x3a3 +#define XK_Itilde              0x3a5 +#define XK_Lcedilla            0x3a6 +#define XK_Emacron             0x3aa +#define XK_Gcedilla            0x3ab +#define XK_Tslash              0x3ac +#define XK_rcedilla            0x3b3 +#define XK_itilde              0x3b5 +#define XK_lcedilla            0x3b6 +#define XK_emacron             0x3ba +#define XK_gcedilla            0x3bb +#define XK_tslash              0x3bc +#define XK_ENG                 0x3bd +#define XK_eng                 0x3bf +#define XK_Amacron             0x3c0 +#define XK_Iogonek             0x3c7 +#define XK_Eabovedot           0x3cc +#define XK_Imacron             0x3cf +#define XK_Ncedilla            0x3d1 +#define XK_Omacron             0x3d2 +#define XK_Kcedilla            0x3d3 +#define XK_Uogonek             0x3d9 +#define XK_Utilde              0x3dd +#define XK_Umacron             0x3de +#define XK_amacron             0x3e0 +#define XK_iogonek             0x3e7 +#define XK_eabovedot           0x3ec +#define XK_imacron             0x3ef +#define XK_ncedilla            0x3f1 +#define XK_omacron             0x3f2 +#define XK_kcedilla            0x3f3 +#define XK_uogonek             0x3f9 +#define XK_utilde              0x3fd +#define XK_umacron             0x3fe +#endif /* XK_LATIN4 */ + +/* + * Katakana + * Byte 3 = 4 + */ + +#ifdef XK_KATAKANA +#define XK_overline				       0x47e +#define XK_kana_fullstop                               0x4a1 +#define XK_kana_openingbracket                         0x4a2 +#define XK_kana_closingbracket                         0x4a3 +#define XK_kana_comma                                  0x4a4 +#define XK_kana_conjunctive                            0x4a5 +#define XK_kana_middledot                              0x4a5  /* deprecated */ +#define XK_kana_WO                                     0x4a6 +#define XK_kana_a                                      0x4a7 +#define XK_kana_i                                      0x4a8 +#define XK_kana_u                                      0x4a9 +#define XK_kana_e                                      0x4aa +#define XK_kana_o                                      0x4ab +#define XK_kana_ya                                     0x4ac +#define XK_kana_yu                                     0x4ad +#define XK_kana_yo                                     0x4ae +#define XK_kana_tsu                                    0x4af +#define XK_kana_tu                                     0x4af  /* deprecated */ +#define XK_prolongedsound                              0x4b0 +#define XK_kana_A                                      0x4b1 +#define XK_kana_I                                      0x4b2 +#define XK_kana_U                                      0x4b3 +#define XK_kana_E                                      0x4b4 +#define XK_kana_O                                      0x4b5 +#define XK_kana_KA                                     0x4b6 +#define XK_kana_KI                                     0x4b7 +#define XK_kana_KU                                     0x4b8 +#define XK_kana_KE                                     0x4b9 +#define XK_kana_KO                                     0x4ba +#define XK_kana_SA                                     0x4bb +#define XK_kana_SHI                                    0x4bc +#define XK_kana_SU                                     0x4bd +#define XK_kana_SE                                     0x4be +#define XK_kana_SO                                     0x4bf +#define XK_kana_TA                                     0x4c0 +#define XK_kana_CHI                                    0x4c1 +#define XK_kana_TI                                     0x4c1  /* deprecated */ +#define XK_kana_TSU                                    0x4c2 +#define XK_kana_TU                                     0x4c2  /* deprecated */ +#define XK_kana_TE                                     0x4c3 +#define XK_kana_TO                                     0x4c4 +#define XK_kana_NA                                     0x4c5 +#define XK_kana_NI                                     0x4c6 +#define XK_kana_NU                                     0x4c7 +#define XK_kana_NE                                     0x4c8 +#define XK_kana_NO                                     0x4c9 +#define XK_kana_HA                                     0x4ca +#define XK_kana_HI                                     0x4cb +#define XK_kana_FU                                     0x4cc +#define XK_kana_HU                                     0x4cc  /* deprecated */ +#define XK_kana_HE                                     0x4cd +#define XK_kana_HO                                     0x4ce +#define XK_kana_MA                                     0x4cf +#define XK_kana_MI                                     0x4d0 +#define XK_kana_MU                                     0x4d1 +#define XK_kana_ME                                     0x4d2 +#define XK_kana_MO                                     0x4d3 +#define XK_kana_YA                                     0x4d4 +#define XK_kana_YU                                     0x4d5 +#define XK_kana_YO                                     0x4d6 +#define XK_kana_RA                                     0x4d7 +#define XK_kana_RI                                     0x4d8 +#define XK_kana_RU                                     0x4d9 +#define XK_kana_RE                                     0x4da +#define XK_kana_RO                                     0x4db +#define XK_kana_WA                                     0x4dc +#define XK_kana_N                                      0x4dd +#define XK_voicedsound                                 0x4de +#define XK_semivoicedsound                             0x4df +#define XK_kana_switch          0xFF7E  /* Alias for mode_switch */ +#endif /* XK_KATAKANA */ + +/* + *  Arabic + *  Byte 3 = 5 + */ + +#ifdef XK_ARABIC +#define XK_Arabic_comma                                0x5ac +#define XK_Arabic_semicolon                            0x5bb +#define XK_Arabic_question_mark                        0x5bf +#define XK_Arabic_hamza                                0x5c1 +#define XK_Arabic_maddaonalef                          0x5c2 +#define XK_Arabic_hamzaonalef                          0x5c3 +#define XK_Arabic_hamzaonwaw                           0x5c4 +#define XK_Arabic_hamzaunderalef                       0x5c5 +#define XK_Arabic_hamzaonyeh                           0x5c6 +#define XK_Arabic_alef                                 0x5c7 +#define XK_Arabic_beh                                  0x5c8 +#define XK_Arabic_tehmarbuta                           0x5c9 +#define XK_Arabic_teh                                  0x5ca +#define XK_Arabic_theh                                 0x5cb +#define XK_Arabic_jeem                                 0x5cc +#define XK_Arabic_hah                                  0x5cd +#define XK_Arabic_khah                                 0x5ce +#define XK_Arabic_dal                                  0x5cf +#define XK_Arabic_thal                                 0x5d0 +#define XK_Arabic_ra                                   0x5d1 +#define XK_Arabic_zain                                 0x5d2 +#define XK_Arabic_seen                                 0x5d3 +#define XK_Arabic_sheen                                0x5d4 +#define XK_Arabic_sad                                  0x5d5 +#define XK_Arabic_dad                                  0x5d6 +#define XK_Arabic_tah                                  0x5d7 +#define XK_Arabic_zah                                  0x5d8 +#define XK_Arabic_ain                                  0x5d9 +#define XK_Arabic_ghain                                0x5da +#define XK_Arabic_tatweel                              0x5e0 +#define XK_Arabic_feh                                  0x5e1 +#define XK_Arabic_qaf                                  0x5e2 +#define XK_Arabic_kaf                                  0x5e3 +#define XK_Arabic_lam                                  0x5e4 +#define XK_Arabic_meem                                 0x5e5 +#define XK_Arabic_noon                                 0x5e6 +#define XK_Arabic_ha                                   0x5e7 +#define XK_Arabic_heh                                  0x5e7  /* deprecated */ +#define XK_Arabic_waw                                  0x5e8 +#define XK_Arabic_alefmaksura                          0x5e9 +#define XK_Arabic_yeh                                  0x5ea +#define XK_Arabic_fathatan                             0x5eb +#define XK_Arabic_dammatan                             0x5ec +#define XK_Arabic_kasratan                             0x5ed +#define XK_Arabic_fatha                                0x5ee +#define XK_Arabic_damma                                0x5ef +#define XK_Arabic_kasra                                0x5f0 +#define XK_Arabic_shadda                               0x5f1 +#define XK_Arabic_sukun                                0x5f2 +#define XK_Arabic_switch        0xFF7E  /* Alias for mode_switch */ +#endif /* XK_ARABIC */ + +/* + * Cyrillic + * Byte 3 = 6 + */ +#ifdef XK_CYRILLIC +#define XK_Serbian_dje                                 0x6a1 +#define XK_Macedonia_gje                               0x6a2 +#define XK_Cyrillic_io                                 0x6a3 +#define XK_Ukrainian_ie                                0x6a4 +#define XK_Ukranian_je                                 0x6a4  /* deprecated */ +#define XK_Macedonia_dse                               0x6a5 +#define XK_Ukrainian_i                                 0x6a6 +#define XK_Ukranian_i                                  0x6a6  /* deprecated */ +#define XK_Ukrainian_yi                                0x6a7 +#define XK_Ukranian_yi                                 0x6a7  /* deprecated */ +#define XK_Cyrillic_je                                 0x6a8 +#define XK_Serbian_je                                  0x6a8  /* deprecated */ +#define XK_Cyrillic_lje                                0x6a9 +#define XK_Serbian_lje                                 0x6a9  /* deprecated */ +#define XK_Cyrillic_nje                                0x6aa +#define XK_Serbian_nje                                 0x6aa  /* deprecated */ +#define XK_Serbian_tshe                                0x6ab +#define XK_Macedonia_kje                               0x6ac +#define XK_Byelorussian_shortu                         0x6ae +#define XK_Cyrillic_dzhe                               0x6af +#define XK_Serbian_dze                                 0x6af  /* deprecated */ +#define XK_numerosign                                  0x6b0 +#define XK_Serbian_DJE                                 0x6b1 +#define XK_Macedonia_GJE                               0x6b2 +#define XK_Cyrillic_IO                                 0x6b3 +#define XK_Ukrainian_IE                                0x6b4 +#define XK_Ukranian_JE                                 0x6b4  /* deprecated */ +#define XK_Macedonia_DSE                               0x6b5 +#define XK_Ukrainian_I                                 0x6b6 +#define XK_Ukranian_I                                  0x6b6  /* deprecated */ +#define XK_Ukrainian_YI                                0x6b7 +#define XK_Ukranian_YI                                 0x6b7  /* deprecated */ +#define XK_Cyrillic_JE                                 0x6b8 +#define XK_Serbian_JE                                  0x6b8  /* deprecated */ +#define XK_Cyrillic_LJE                                0x6b9 +#define XK_Serbian_LJE                                 0x6b9  /* deprecated */ +#define XK_Cyrillic_NJE                                0x6ba +#define XK_Serbian_NJE                                 0x6ba  /* deprecated */ +#define XK_Serbian_TSHE                                0x6bb +#define XK_Macedonia_KJE                               0x6bc +#define XK_Byelorussian_SHORTU                         0x6be +#define XK_Cyrillic_DZHE                               0x6bf +#define XK_Serbian_DZE                                 0x6bf  /* deprecated */ +#define XK_Cyrillic_yu                                 0x6c0 +#define XK_Cyrillic_a                                  0x6c1 +#define XK_Cyrillic_be                                 0x6c2 +#define XK_Cyrillic_tse                                0x6c3 +#define XK_Cyrillic_de                                 0x6c4 +#define XK_Cyrillic_ie                                 0x6c5 +#define XK_Cyrillic_ef                                 0x6c6 +#define XK_Cyrillic_ghe                                0x6c7 +#define XK_Cyrillic_ha                                 0x6c8 +#define XK_Cyrillic_i                                  0x6c9 +#define XK_Cyrillic_shorti                             0x6ca +#define XK_Cyrillic_ka                                 0x6cb +#define XK_Cyrillic_el                                 0x6cc +#define XK_Cyrillic_em                                 0x6cd +#define XK_Cyrillic_en                                 0x6ce +#define XK_Cyrillic_o                                  0x6cf +#define XK_Cyrillic_pe                                 0x6d0 +#define XK_Cyrillic_ya                                 0x6d1 +#define XK_Cyrillic_er                                 0x6d2 +#define XK_Cyrillic_es                                 0x6d3 +#define XK_Cyrillic_te                                 0x6d4 +#define XK_Cyrillic_u                                  0x6d5 +#define XK_Cyrillic_zhe                                0x6d6 +#define XK_Cyrillic_ve                                 0x6d7 +#define XK_Cyrillic_softsign                           0x6d8 +#define XK_Cyrillic_yeru                               0x6d9 +#define XK_Cyrillic_ze                                 0x6da +#define XK_Cyrillic_sha                                0x6db +#define XK_Cyrillic_e                                  0x6dc +#define XK_Cyrillic_shcha                              0x6dd +#define XK_Cyrillic_che                                0x6de +#define XK_Cyrillic_hardsign                           0x6df +#define XK_Cyrillic_YU                                 0x6e0 +#define XK_Cyrillic_A                                  0x6e1 +#define XK_Cyrillic_BE                                 0x6e2 +#define XK_Cyrillic_TSE                                0x6e3 +#define XK_Cyrillic_DE                                 0x6e4 +#define XK_Cyrillic_IE                                 0x6e5 +#define XK_Cyrillic_EF                                 0x6e6 +#define XK_Cyrillic_GHE                                0x6e7 +#define XK_Cyrillic_HA                                 0x6e8 +#define XK_Cyrillic_I                                  0x6e9 +#define XK_Cyrillic_SHORTI                             0x6ea +#define XK_Cyrillic_KA                                 0x6eb +#define XK_Cyrillic_EL                                 0x6ec +#define XK_Cyrillic_EM                                 0x6ed +#define XK_Cyrillic_EN                                 0x6ee +#define XK_Cyrillic_O                                  0x6ef +#define XK_Cyrillic_PE                                 0x6f0 +#define XK_Cyrillic_YA                                 0x6f1 +#define XK_Cyrillic_ER                                 0x6f2 +#define XK_Cyrillic_ES                                 0x6f3 +#define XK_Cyrillic_TE                                 0x6f4 +#define XK_Cyrillic_U                                  0x6f5 +#define XK_Cyrillic_ZHE                                0x6f6 +#define XK_Cyrillic_VE                                 0x6f7 +#define XK_Cyrillic_SOFTSIGN                           0x6f8 +#define XK_Cyrillic_YERU                               0x6f9 +#define XK_Cyrillic_ZE                                 0x6fa +#define XK_Cyrillic_SHA                                0x6fb +#define XK_Cyrillic_E                                  0x6fc +#define XK_Cyrillic_SHCHA                              0x6fd +#define XK_Cyrillic_CHE                                0x6fe +#define XK_Cyrillic_HARDSIGN                           0x6ff +#endif /* XK_CYRILLIC */ + +/* + * Greek + * Byte 3 = 7 + */ + +#ifdef XK_GREEK +#define XK_Greek_ALPHAaccent                           0x7a1 +#define XK_Greek_EPSILONaccent                         0x7a2 +#define XK_Greek_ETAaccent                             0x7a3 +#define XK_Greek_IOTAaccent                            0x7a4 +#define XK_Greek_IOTAdieresis                          0x7a5 +#define XK_Greek_OMICRONaccent                         0x7a7 +#define XK_Greek_UPSILONaccent                         0x7a8 +#define XK_Greek_UPSILONdieresis                       0x7a9 +#define XK_Greek_OMEGAaccent                           0x7ab +#define XK_Greek_accentdieresis                        0x7ae +#define XK_Greek_horizbar                              0x7af +#define XK_Greek_alphaaccent                           0x7b1 +#define XK_Greek_epsilonaccent                         0x7b2 +#define XK_Greek_etaaccent                             0x7b3 +#define XK_Greek_iotaaccent                            0x7b4 +#define XK_Greek_iotadieresis                          0x7b5 +#define XK_Greek_iotaaccentdieresis                    0x7b6 +#define XK_Greek_omicronaccent                         0x7b7 +#define XK_Greek_upsilonaccent                         0x7b8 +#define XK_Greek_upsilondieresis                       0x7b9 +#define XK_Greek_upsilonaccentdieresis                 0x7ba +#define XK_Greek_omegaaccent                           0x7bb +#define XK_Greek_ALPHA                                 0x7c1 +#define XK_Greek_BETA                                  0x7c2 +#define XK_Greek_GAMMA                                 0x7c3 +#define XK_Greek_DELTA                                 0x7c4 +#define XK_Greek_EPSILON                               0x7c5 +#define XK_Greek_ZETA                                  0x7c6 +#define XK_Greek_ETA                                   0x7c7 +#define XK_Greek_THETA                                 0x7c8 +#define XK_Greek_IOTA                                  0x7c9 +#define XK_Greek_KAPPA                                 0x7ca +#define XK_Greek_LAMDA                                 0x7cb +#define XK_Greek_LAMBDA                                0x7cb +#define XK_Greek_MU                                    0x7cc +#define XK_Greek_NU                                    0x7cd +#define XK_Greek_XI                                    0x7ce +#define XK_Greek_OMICRON                               0x7cf +#define XK_Greek_PI                                    0x7d0 +#define XK_Greek_RHO                                   0x7d1 +#define XK_Greek_SIGMA                                 0x7d2 +#define XK_Greek_TAU                                   0x7d4 +#define XK_Greek_UPSILON                               0x7d5 +#define XK_Greek_PHI                                   0x7d6 +#define XK_Greek_CHI                                   0x7d7 +#define XK_Greek_PSI                                   0x7d8 +#define XK_Greek_OMEGA                                 0x7d9 +#define XK_Greek_alpha                                 0x7e1 +#define XK_Greek_beta                                  0x7e2 +#define XK_Greek_gamma                                 0x7e3 +#define XK_Greek_delta                                 0x7e4 +#define XK_Greek_epsilon                               0x7e5 +#define XK_Greek_zeta                                  0x7e6 +#define XK_Greek_eta                                   0x7e7 +#define XK_Greek_theta                                 0x7e8 +#define XK_Greek_iota                                  0x7e9 +#define XK_Greek_kappa                                 0x7ea +#define XK_Greek_lamda                                 0x7eb +#define XK_Greek_lambda                                0x7eb +#define XK_Greek_mu                                    0x7ec +#define XK_Greek_nu                                    0x7ed +#define XK_Greek_xi                                    0x7ee +#define XK_Greek_omicron                               0x7ef +#define XK_Greek_pi                                    0x7f0 +#define XK_Greek_rho                                   0x7f1 +#define XK_Greek_sigma                                 0x7f2 +#define XK_Greek_finalsmallsigma                       0x7f3 +#define XK_Greek_tau                                   0x7f4 +#define XK_Greek_upsilon                               0x7f5 +#define XK_Greek_phi                                   0x7f6 +#define XK_Greek_chi                                   0x7f7 +#define XK_Greek_psi                                   0x7f8 +#define XK_Greek_omega                                 0x7f9 +#define XK_Greek_switch         0xFF7E  /* Alias for mode_switch */ +#endif /* XK_GREEK */ + +/* + * Technical + * Byte 3 = 8 + */ + +#ifdef XK_TECHNICAL +#define XK_leftradical                                 0x8a1 +#define XK_topleftradical                              0x8a2 +#define XK_horizconnector                              0x8a3 +#define XK_topintegral                                 0x8a4 +#define XK_botintegral                                 0x8a5 +#define XK_vertconnector                               0x8a6 +#define XK_topleftsqbracket                            0x8a7 +#define XK_botleftsqbracket                            0x8a8 +#define XK_toprightsqbracket                           0x8a9 +#define XK_botrightsqbracket                           0x8aa +#define XK_topleftparens                               0x8ab +#define XK_botleftparens                               0x8ac +#define XK_toprightparens                              0x8ad +#define XK_botrightparens                              0x8ae +#define XK_leftmiddlecurlybrace                        0x8af +#define XK_rightmiddlecurlybrace                       0x8b0 +#define XK_topleftsummation                            0x8b1 +#define XK_botleftsummation                            0x8b2 +#define XK_topvertsummationconnector                   0x8b3 +#define XK_botvertsummationconnector                   0x8b4 +#define XK_toprightsummation                           0x8b5 +#define XK_botrightsummation                           0x8b6 +#define XK_rightmiddlesummation                        0x8b7 +#define XK_lessthanequal                               0x8bc +#define XK_notequal                                    0x8bd +#define XK_greaterthanequal                            0x8be +#define XK_integral                                    0x8bf +#define XK_therefore                                   0x8c0 +#define XK_variation                                   0x8c1 +#define XK_infinity                                    0x8c2 +#define XK_nabla                                       0x8c5 +#define XK_approximate                                 0x8c8 +#define XK_similarequal                                0x8c9 +#define XK_ifonlyif                                    0x8cd +#define XK_implies                                     0x8ce +#define XK_identical                                   0x8cf +#define XK_radical                                     0x8d6 +#define XK_includedin                                  0x8da +#define XK_includes                                    0x8db +#define XK_intersection                                0x8dc +#define XK_union                                       0x8dd +#define XK_logicaland                                  0x8de +#define XK_logicalor                                   0x8df +#define XK_partialderivative                           0x8ef +#define XK_function                                    0x8f6 +#define XK_leftarrow                                   0x8fb +#define XK_uparrow                                     0x8fc +#define XK_rightarrow                                  0x8fd +#define XK_downarrow                                   0x8fe +#endif /* XK_TECHNICAL */ + +/* + *  Special + *  Byte 3 = 9 + */ + +#ifdef XK_SPECIAL +#define XK_blank                                       0x9df +#define XK_soliddiamond                                0x9e0 +#define XK_checkerboard                                0x9e1 +#define XK_ht                                          0x9e2 +#define XK_ff                                          0x9e3 +#define XK_cr                                          0x9e4 +#define XK_lf                                          0x9e5 +#define XK_nl                                          0x9e8 +#define XK_vt                                          0x9e9 +#define XK_lowrightcorner                              0x9ea +#define XK_uprightcorner                               0x9eb +#define XK_upleftcorner                                0x9ec +#define XK_lowleftcorner                               0x9ed +#define XK_crossinglines                               0x9ee +#define XK_horizlinescan1                              0x9ef +#define XK_horizlinescan3                              0x9f0 +#define XK_horizlinescan5                              0x9f1 +#define XK_horizlinescan7                              0x9f2 +#define XK_horizlinescan9                              0x9f3 +#define XK_leftt                                       0x9f4 +#define XK_rightt                                      0x9f5 +#define XK_bott                                        0x9f6 +#define XK_topt                                        0x9f7 +#define XK_vertbar                                     0x9f8 +#endif /* XK_SPECIAL */ + +/* + *  Publishing + *  Byte 3 = a + */ + +#ifdef XK_PUBLISHING +#define XK_emspace                                     0xaa1 +#define XK_enspace                                     0xaa2 +#define XK_em3space                                    0xaa3 +#define XK_em4space                                    0xaa4 +#define XK_digitspace                                  0xaa5 +#define XK_punctspace                                  0xaa6 +#define XK_thinspace                                   0xaa7 +#define XK_hairspace                                   0xaa8 +#define XK_emdash                                      0xaa9 +#define XK_endash                                      0xaaa +#define XK_signifblank                                 0xaac +#define XK_ellipsis                                    0xaae +#define XK_doubbaselinedot                             0xaaf +#define XK_onethird                                    0xab0 +#define XK_twothirds                                   0xab1 +#define XK_onefifth                                    0xab2 +#define XK_twofifths                                   0xab3 +#define XK_threefifths                                 0xab4 +#define XK_fourfifths                                  0xab5 +#define XK_onesixth                                    0xab6 +#define XK_fivesixths                                  0xab7 +#define XK_careof                                      0xab8 +#define XK_figdash                                     0xabb +#define XK_leftanglebracket                            0xabc +#define XK_decimalpoint                                0xabd +#define XK_rightanglebracket                           0xabe +#define XK_marker                                      0xabf +#define XK_oneeighth                                   0xac3 +#define XK_threeeighths                                0xac4 +#define XK_fiveeighths                                 0xac5 +#define XK_seveneighths                                0xac6 +#define XK_trademark                                   0xac9 +#define XK_signaturemark                               0xaca +#define XK_trademarkincircle                           0xacb +#define XK_leftopentriangle                            0xacc +#define XK_rightopentriangle                           0xacd +#define XK_emopencircle                                0xace +#define XK_emopenrectangle                             0xacf +#define XK_leftsinglequotemark                         0xad0 +#define XK_rightsinglequotemark                        0xad1 +#define XK_leftdoublequotemark                         0xad2 +#define XK_rightdoublequotemark                        0xad3 +#define XK_prescription                                0xad4 +#define XK_minutes                                     0xad6 +#define XK_seconds                                     0xad7 +#define XK_latincross                                  0xad9 +#define XK_hexagram                                    0xada +#define XK_filledrectbullet                            0xadb +#define XK_filledlefttribullet                         0xadc +#define XK_filledrighttribullet                        0xadd +#define XK_emfilledcircle                              0xade +#define XK_emfilledrect                                0xadf +#define XK_enopencircbullet                            0xae0 +#define XK_enopensquarebullet                          0xae1 +#define XK_openrectbullet                              0xae2 +#define XK_opentribulletup                             0xae3 +#define XK_opentribulletdown                           0xae4 +#define XK_openstar                                    0xae5 +#define XK_enfilledcircbullet                          0xae6 +#define XK_enfilledsqbullet                            0xae7 +#define XK_filledtribulletup                           0xae8 +#define XK_filledtribulletdown                         0xae9 +#define XK_leftpointer                                 0xaea +#define XK_rightpointer                                0xaeb +#define XK_club                                        0xaec +#define XK_diamond                                     0xaed +#define XK_heart                                       0xaee +#define XK_maltesecross                                0xaf0 +#define XK_dagger                                      0xaf1 +#define XK_doubledagger                                0xaf2 +#define XK_checkmark                                   0xaf3 +#define XK_ballotcross                                 0xaf4 +#define XK_musicalsharp                                0xaf5 +#define XK_musicalflat                                 0xaf6 +#define XK_malesymbol                                  0xaf7 +#define XK_femalesymbol                                0xaf8 +#define XK_telephone                                   0xaf9 +#define XK_telephonerecorder                           0xafa +#define XK_phonographcopyright                         0xafb +#define XK_caret                                       0xafc +#define XK_singlelowquotemark                          0xafd +#define XK_doublelowquotemark                          0xafe +#define XK_cursor                                      0xaff +#endif /* XK_PUBLISHING */ + +/* + *  APL + *  Byte 3 = b + */ + +#ifdef XK_APL +#define XK_leftcaret                                   0xba3 +#define XK_rightcaret                                  0xba6 +#define XK_downcaret                                   0xba8 +#define XK_upcaret                                     0xba9 +#define XK_overbar                                     0xbc0 +#define XK_downtack                                    0xbc2 +#define XK_upshoe                                      0xbc3 +#define XK_downstile                                   0xbc4 +#define XK_underbar                                    0xbc6 +#define XK_jot                                         0xbca +#define XK_quad                                        0xbcc +#define XK_uptack                                      0xbce +#define XK_circle                                      0xbcf +#define XK_upstile                                     0xbd3 +#define XK_downshoe                                    0xbd6 +#define XK_rightshoe                                   0xbd8 +#define XK_leftshoe                                    0xbda +#define XK_lefttack                                    0xbdc +#define XK_righttack                                   0xbfc +#endif /* XK_APL */ + +/* + * Hebrew + * Byte 3 = c + */ + +#ifdef XK_HEBREW +#define XK_hebrew_doublelowline                        0xcdf +#define XK_hebrew_aleph                                0xce0 +#define XK_hebrew_bet                                  0xce1 +#define XK_hebrew_beth                                 0xce1  /* deprecated */ +#define XK_hebrew_gimel                                0xce2 +#define XK_hebrew_gimmel                               0xce2  /* deprecated */ +#define XK_hebrew_dalet                                0xce3 +#define XK_hebrew_daleth                               0xce3  /* deprecated */ +#define XK_hebrew_he                                   0xce4 +#define XK_hebrew_waw                                  0xce5 +#define XK_hebrew_zain                                 0xce6 +#define XK_hebrew_zayin                                0xce6  /* deprecated */ +#define XK_hebrew_chet                                 0xce7 +#define XK_hebrew_het                                  0xce7  /* deprecated */ +#define XK_hebrew_tet                                  0xce8 +#define XK_hebrew_teth                                 0xce8  /* deprecated */ +#define XK_hebrew_yod                                  0xce9 +#define XK_hebrew_finalkaph                            0xcea +#define XK_hebrew_kaph                                 0xceb +#define XK_hebrew_lamed                                0xcec +#define XK_hebrew_finalmem                             0xced +#define XK_hebrew_mem                                  0xcee +#define XK_hebrew_finalnun                             0xcef +#define XK_hebrew_nun                                  0xcf0 +#define XK_hebrew_samech                               0xcf1 +#define XK_hebrew_samekh                               0xcf1  /* deprecated */ +#define XK_hebrew_ayin                                 0xcf2 +#define XK_hebrew_finalpe                              0xcf3 +#define XK_hebrew_pe                                   0xcf4 +#define XK_hebrew_finalzade                            0xcf5 +#define XK_hebrew_finalzadi                            0xcf5  /* deprecated */ +#define XK_hebrew_zade                                 0xcf6 +#define XK_hebrew_zadi                                 0xcf6  /* deprecated */ +#define XK_hebrew_qoph                                 0xcf7 +#define XK_hebrew_kuf                                  0xcf7  /* deprecated */ +#define XK_hebrew_resh                                 0xcf8 +#define XK_hebrew_shin                                 0xcf9 +#define XK_hebrew_taw                                  0xcfa +#define XK_hebrew_taf                                  0xcfa  /* deprecated */ +#define XK_Hebrew_switch        0xFF7E  /* Alias for mode_switch */ +#endif /* XK_HEBREW */ + +/* + * Thai + * Byte 3 = d + */ + +#ifdef XK_THAI +#define XK_Thai_kokai					0xda1 +#define XK_Thai_khokhai					0xda2 +#define XK_Thai_khokhuat				0xda3 +#define XK_Thai_khokhwai				0xda4 +#define XK_Thai_khokhon					0xda5 +#define XK_Thai_khorakhang			        0xda6   +#define XK_Thai_ngongu					0xda7   +#define XK_Thai_chochan					0xda8   +#define XK_Thai_choching				0xda9    +#define XK_Thai_chochang				0xdaa   +#define XK_Thai_soso					0xdab +#define XK_Thai_chochoe					0xdac +#define XK_Thai_yoying					0xdad +#define XK_Thai_dochada					0xdae +#define XK_Thai_topatak					0xdaf +#define XK_Thai_thothan					0xdb0 +#define XK_Thai_thonangmontho			        0xdb1 +#define XK_Thai_thophuthao			        0xdb2 +#define XK_Thai_nonen					0xdb3 +#define XK_Thai_dodek					0xdb4 +#define XK_Thai_totao					0xdb5 +#define XK_Thai_thothung				0xdb6 +#define XK_Thai_thothahan				0xdb7 +#define XK_Thai_thothong	 			0xdb8 +#define XK_Thai_nonu					0xdb9 +#define XK_Thai_bobaimai				0xdba +#define XK_Thai_popla					0xdbb +#define XK_Thai_phophung				0xdbc +#define XK_Thai_fofa					0xdbd +#define XK_Thai_phophan					0xdbe +#define XK_Thai_fofan					0xdbf +#define XK_Thai_phosamphao			        0xdc0 +#define XK_Thai_moma					0xdc1 +#define XK_Thai_yoyak					0xdc2 +#define XK_Thai_rorua					0xdc3 +#define XK_Thai_ru					0xdc4 +#define XK_Thai_loling					0xdc5 +#define XK_Thai_lu					0xdc6 +#define XK_Thai_wowaen					0xdc7 +#define XK_Thai_sosala					0xdc8 +#define XK_Thai_sorusi					0xdc9 +#define XK_Thai_sosua					0xdca +#define XK_Thai_hohip					0xdcb +#define XK_Thai_lochula					0xdcc +#define XK_Thai_oang					0xdcd +#define XK_Thai_honokhuk				0xdce +#define XK_Thai_paiyannoi				0xdcf +#define XK_Thai_saraa					0xdd0 +#define XK_Thai_maihanakat				0xdd1 +#define XK_Thai_saraaa					0xdd2 +#define XK_Thai_saraam					0xdd3 +#define XK_Thai_sarai					0xdd4    +#define XK_Thai_saraii					0xdd5    +#define XK_Thai_saraue					0xdd6     +#define XK_Thai_sarauee					0xdd7     +#define XK_Thai_sarau					0xdd8     +#define XK_Thai_sarauu					0xdd9    +#define XK_Thai_phinthu					0xdda +#define XK_Thai_maihanakat_maitho   			0xdde +#define XK_Thai_baht					0xddf +#define XK_Thai_sarae					0xde0     +#define XK_Thai_saraae					0xde1 +#define XK_Thai_sarao					0xde2 +#define XK_Thai_saraaimaimuan				0xde3    +#define XK_Thai_saraaimaimalai				0xde4   +#define XK_Thai_lakkhangyao				0xde5 +#define XK_Thai_maiyamok				0xde6 +#define XK_Thai_maitaikhu				0xde7 +#define XK_Thai_maiek					0xde8    +#define XK_Thai_maitho					0xde9 +#define XK_Thai_maitri					0xdea +#define XK_Thai_maichattawa				0xdeb +#define XK_Thai_thanthakhat				0xdec +#define XK_Thai_nikhahit				0xded +#define XK_Thai_leksun					0xdf0  +#define XK_Thai_leknung					0xdf1   +#define XK_Thai_leksong					0xdf2  +#define XK_Thai_leksam					0xdf3 +#define XK_Thai_leksi					0xdf4   +#define XK_Thai_lekha					0xdf5   +#define XK_Thai_lekhok					0xdf6   +#define XK_Thai_lekchet					0xdf7   +#define XK_Thai_lekpaet					0xdf8   +#define XK_Thai_lekkao					0xdf9  +#endif /* XK_THAI */ + +/* + *   Korean + *   Byte 3 = e + */ + +#ifdef XK_KOREAN + +#define XK_Hangul		0xff31    /* Hangul start/stop(toggle) */ +#define XK_Hangul_Start		0xff32    /* Hangul start */ +#define XK_Hangul_End		0xff33    /* Hangul end, English start */ +#define XK_Hangul_Hanja		0xff34    /* Start Hangul->Hanja Conversion */ +#define XK_Hangul_Jamo		0xff35    /* Hangul Jamo mode */ +#define XK_Hangul_Romaja	0xff36    /* Hangul Romaja mode */ +#define XK_Hangul_Codeinput	0xff37    /* Hangul code input mode */ +#define XK_Hangul_Jeonja	0xff38    /* Jeonja mode */ +#define XK_Hangul_Banja		0xff39    /* Banja mode */ +#define XK_Hangul_PreHanja	0xff3a    /* Pre Hanja conversion */ +#define XK_Hangul_PostHanja	0xff3b    /* Post Hanja conversion */ +#define XK_Hangul_SingleCandidate	0xff3c    /* Single candidate */ +#define XK_Hangul_MultipleCandidate	0xff3d    /* Multiple candidate */ +#define XK_Hangul_PreviousCandidate	0xff3e    /* Previous candidate */ +#define XK_Hangul_Special	0xff3f    /* Special symbols */ +#define XK_Hangul_switch	0xFF7E    /* Alias for mode_switch */ + +/* Hangul Consonant Characters */ +#define XK_Hangul_Kiyeog				0xea1 +#define XK_Hangul_SsangKiyeog				0xea2 +#define XK_Hangul_KiyeogSios				0xea3 +#define XK_Hangul_Nieun					0xea4 +#define XK_Hangul_NieunJieuj				0xea5 +#define XK_Hangul_NieunHieuh				0xea6 +#define XK_Hangul_Dikeud				0xea7 +#define XK_Hangul_SsangDikeud				0xea8 +#define XK_Hangul_Rieul					0xea9 +#define XK_Hangul_RieulKiyeog				0xeaa +#define XK_Hangul_RieulMieum				0xeab +#define XK_Hangul_RieulPieub				0xeac +#define XK_Hangul_RieulSios				0xead +#define XK_Hangul_RieulTieut				0xeae +#define XK_Hangul_RieulPhieuf				0xeaf +#define XK_Hangul_RieulHieuh				0xeb0 +#define XK_Hangul_Mieum					0xeb1 +#define XK_Hangul_Pieub					0xeb2 +#define XK_Hangul_SsangPieub				0xeb3 +#define XK_Hangul_PieubSios				0xeb4 +#define XK_Hangul_Sios					0xeb5 +#define XK_Hangul_SsangSios				0xeb6 +#define XK_Hangul_Ieung					0xeb7 +#define XK_Hangul_Jieuj					0xeb8 +#define XK_Hangul_SsangJieuj				0xeb9 +#define XK_Hangul_Cieuc					0xeba +#define XK_Hangul_Khieuq				0xebb +#define XK_Hangul_Tieut					0xebc +#define XK_Hangul_Phieuf				0xebd +#define XK_Hangul_Hieuh					0xebe + +/* Hangul Vowel Characters */ +#define XK_Hangul_A					0xebf +#define XK_Hangul_AE					0xec0 +#define XK_Hangul_YA					0xec1 +#define XK_Hangul_YAE					0xec2 +#define XK_Hangul_EO					0xec3 +#define XK_Hangul_E					0xec4 +#define XK_Hangul_YEO					0xec5 +#define XK_Hangul_YE					0xec6 +#define XK_Hangul_O					0xec7 +#define XK_Hangul_WA					0xec8 +#define XK_Hangul_WAE					0xec9 +#define XK_Hangul_OE					0xeca +#define XK_Hangul_YO					0xecb +#define XK_Hangul_U					0xecc +#define XK_Hangul_WEO					0xecd +#define XK_Hangul_WE					0xece +#define XK_Hangul_WI					0xecf +#define XK_Hangul_YU					0xed0 +#define XK_Hangul_EU					0xed1 +#define XK_Hangul_YI					0xed2 +#define XK_Hangul_I					0xed3 + +/* Hangul syllable-final (JongSeong) Characters */ +#define XK_Hangul_J_Kiyeog				0xed4 +#define XK_Hangul_J_SsangKiyeog				0xed5 +#define XK_Hangul_J_KiyeogSios				0xed6 +#define XK_Hangul_J_Nieun				0xed7 +#define XK_Hangul_J_NieunJieuj				0xed8 +#define XK_Hangul_J_NieunHieuh				0xed9 +#define XK_Hangul_J_Dikeud				0xeda +#define XK_Hangul_J_Rieul				0xedb +#define XK_Hangul_J_RieulKiyeog				0xedc +#define XK_Hangul_J_RieulMieum				0xedd +#define XK_Hangul_J_RieulPieub				0xede +#define XK_Hangul_J_RieulSios				0xedf +#define XK_Hangul_J_RieulTieut				0xee0 +#define XK_Hangul_J_RieulPhieuf				0xee1 +#define XK_Hangul_J_RieulHieuh				0xee2 +#define XK_Hangul_J_Mieum				0xee3 +#define XK_Hangul_J_Pieub				0xee4 +#define XK_Hangul_J_PieubSios				0xee5 +#define XK_Hangul_J_Sios				0xee6 +#define XK_Hangul_J_SsangSios				0xee7 +#define XK_Hangul_J_Ieung				0xee8 +#define XK_Hangul_J_Jieuj				0xee9 +#define XK_Hangul_J_Cieuc				0xeea +#define XK_Hangul_J_Khieuq				0xeeb +#define XK_Hangul_J_Tieut				0xeec +#define XK_Hangul_J_Phieuf				0xeed +#define XK_Hangul_J_Hieuh				0xeee + +/* Ancient Hangul Consonant Characters */ +#define XK_Hangul_RieulYeorinHieuh			0xeef +#define XK_Hangul_SunkyeongeumMieum			0xef0 +#define XK_Hangul_SunkyeongeumPieub			0xef1 +#define XK_Hangul_PanSios				0xef2 +#define XK_Hangul_KkogjiDalrinIeung			0xef3 +#define XK_Hangul_SunkyeongeumPhieuf			0xef4 +#define XK_Hangul_YeorinHieuh				0xef5 + +/* Ancient Hangul Vowel Characters */ +#define XK_Hangul_AraeA					0xef6 +#define XK_Hangul_AraeAE				0xef7 + +/* Ancient Hangul syllable-final (JongSeong) Characters */ +#define XK_Hangul_J_PanSios				0xef8 +#define XK_Hangul_J_KkogjiDalrinIeung			0xef9 +#define XK_Hangul_J_YeorinHieuh				0xefa + +/* Korean currency symbol */ +#define XK_Korean_Won					0xeff + +#endif /* XK_KOREAN */ + +/* Euro currency symbol */ +#define XK_EuroSign 0x20ac + +#endif diff --git a/3rdParty/LibVNC/src/rfb/rfb.h b/3rdParty/LibVNC/src/rfb/rfb.h new file mode 100644 index 0000000..a03ab21 --- /dev/null +++ b/3rdParty/LibVNC/src/rfb/rfb.h @@ -0,0 +1,989 @@ +#ifndef RFB_H +#define RFB_H + +/* + * rfb.h - header file for RFB DDX implementation. + */ + +/* + *  Copyright (C) 2005 Rohit Kumar <rokumar@novell.com>, + *                     Johannes E. Schindelin <johannes.schindelin@gmx.de> + *  Copyright (C) 2002 RealVNC Ltd. + *  OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>. + *  Original Xvnc code 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. + */ + +#if(defined __cplusplus) +extern "C" +{ +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <rfb/rfbproto.h> + +#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef __MINGW32__ +#undef SOCKET +#include <winsock2.h> +#endif + +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD +#include <pthread.h> +#if 0 /* debugging */ +#define LOCK(mutex) (rfbLog("%s:%d LOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_lock(&(mutex))) +#define UNLOCK(mutex) (rfbLog("%s:%d UNLOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_unlock(&(mutex))) +#define MUTEX(mutex) pthread_mutex_t (mutex) +#define INIT_MUTEX(mutex) (rfbLog("%s:%d INIT_MUTEX(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_init(&(mutex),NULL)) +#define TINI_MUTEX(mutex) (rfbLog("%s:%d TINI_MUTEX(%s)\n",__FILE__,__LINE__,#mutex), pthread_mutex_destroy(&(mutex))) +#define TSIGNAL(cond) (rfbLog("%s:%d TSIGNAL(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_signal(&(cond))) +#define WAIT(cond,mutex) (rfbLog("%s:%d WAIT(%s,%s)\n",__FILE__,__LINE__,#cond,#mutex), pthread_cond_wait(&(cond),&(mutex))) +#define COND(cond) pthread_cond_t (cond) +#define INIT_COND(cond) (rfbLog("%s:%d INIT_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_init(&(cond),NULL)) +#define TINI_COND(cond) (rfbLog("%s:%d TINI_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_destroy(&(cond))) +#define IF_PTHREADS(x) x +#else +#if !NONETWORK +#define LOCK(mutex) pthread_mutex_lock(&(mutex)); +#define UNLOCK(mutex) pthread_mutex_unlock(&(mutex)); +#endif +#define MUTEX(mutex) pthread_mutex_t (mutex) +#define INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL) +#define TINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex)) +#define TSIGNAL(cond) pthread_cond_signal(&(cond)) +#define WAIT(cond,mutex) pthread_cond_wait(&(cond),&(mutex)) +#define COND(cond) pthread_cond_t (cond) +#define INIT_COND(cond) pthread_cond_init(&(cond),NULL) +#define TINI_COND(cond) pthread_cond_destroy(&(cond)) +#define IF_PTHREADS(x) x +#endif +#else +#define LOCK(mutex) +#define UNLOCK(mutex) +#define MUTEX(mutex) +#define INIT_MUTEX(mutex) +#define TINI_MUTEX(mutex) +#define TSIGNAL(cond) +#define WAIT(cond,mutex) this_is_unsupported +#define COND(cond) +#define INIT_COND(cond) +#define TINI_COND(cond) +#define IF_PTHREADS(x) +#endif + +/* end of stuff for autoconf */ + +/* if you use pthreads, but don't define LIBVNCSERVER_HAVE_LIBPTHREAD, the structs +   get all mixed up. So this gives a linker error reminding you to compile +   the library and your application (at least the parts including rfb.h) +   with the same support for pthreads. */ +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD +#ifdef LIBVNCSERVER_HAVE_LIBZ +#define rfbInitServer rfbInitServerWithPthreadsAndZRLE +#else +#define rfbInitServer rfbInitServerWithPthreadsButWithoutZRLE +#endif +#else +#ifdef LIBVNCSERVER_HAVE_LIBZ +#define rfbInitServer rfbInitServerWithoutPthreadsButWithZRLE +#else +#define rfbInitServer rfbInitServerWithoutPthreadsAndZRLE +#endif +#endif + +struct _rfbClientRec; +struct _rfbScreenInfo; +struct rfbCursor; + +enum rfbNewClientAction { +	RFB_CLIENT_ACCEPT, +	RFB_CLIENT_ON_HOLD, +	RFB_CLIENT_REFUSE +}; + +enum rfbSocketState { +	RFB_SOCKET_INIT, +	RFB_SOCKET_READY, +	RFB_SOCKET_SHUTDOWN +}; + +typedef void (*rfbKbdAddEventProcPtr) (rfbBool down, rfbKeySym keySym, struct _rfbClientRec* cl); +typedef void (*rfbKbdReleaseAllKeysProcPtr) (struct _rfbClientRec* cl); +typedef void (*rfbPtrAddEventProcPtr) (int buttonMask, int x, int y, struct _rfbClientRec* cl); +typedef void (*rfbSetXCutTextProcPtr) (char* str,int len, struct _rfbClientRec* cl); +typedef struct rfbCursor* (*rfbGetCursorProcPtr) (struct _rfbClientRec* pScreen); +typedef rfbBool (*rfbSetTranslateFunctionProcPtr)(struct _rfbClientRec* cl); +typedef rfbBool (*rfbPasswordCheckProcPtr)(struct _rfbClientRec* cl,const char* encryptedPassWord,int len); +typedef enum rfbNewClientAction (*rfbNewClientHookPtr)(struct _rfbClientRec* cl); +typedef void (*rfbDisplayHookPtr)(struct _rfbClientRec* cl); +/* support the capability to view the caps/num/scroll states of the X server */ +typedef int  (*rfbGetKeyboardLedStateHookPtr)(struct _rfbScreenInfo* screen); +/* If x==1 and y==1 then set the whole display + * else find the window underneath x and y and set the framebuffer to the dimensions + * of that window + */ +typedef void (*rfbSetSingleWindowProcPtr) (struct _rfbClientRec* cl, int x, int y); +/* Status determines if the X11 server permits input from the local user  + * status==0 or 1 + */ +typedef void (*rfbSetServerInputProcPtr) (struct _rfbClientRec* cl, int status); +/* Permit the server to allow or deny filetransfers.   This is defaulted to deny + * It is called when a client initiates a connection to determine if it is permitted. + */ +typedef int  (*rfbFileTransferPermitted) (struct _rfbClientRec* cl); +/* Handle the textchat messages */ +typedef void (*rfbSetTextChat) (struct _rfbClientRec* cl, int length, char *string); + +typedef struct { +  uint32_t count; +  rfbBool is16; /* is the data format short? */ +  union { +    uint8_t* bytes; +    uint16_t* shorts; +  } data; /* there have to be count*3 entries */ +} rfbColourMap; + +/* + * Security handling (RFB protocol version 3.7) + */ + +typedef struct _rfbSecurity { +	uint8_t type; +	void (*handler)(struct _rfbClientRec* cl); +	struct _rfbSecurity* next; +} rfbSecurityHandler; + +/* + * Protocol extension handling. + */ + +typedef struct _rfbProtocolExtension { +	/* returns FALSE if extension should be deactivated for client. +	   if newClient == NULL, it is always deactivated. */ +	rfbBool (*newClient)(struct _rfbClientRec* client, void** data); +	/* returns FALSE if extension should be deactivated for client. +	   if init == NULL, it stays activated. */ +	rfbBool (*init)(struct _rfbClientRec* client, void* data); +	/* if pseudoEncodings is not NULL, it contains a 0 terminated +	   list of the pseudo encodings handled by this extension. */ +	int *pseudoEncodings; +	/* returns TRUE if that pseudo encoding is handled by the extension. +	   encodingNumber==0 means "reset encodings". */ +	rfbBool (*enablePseudoEncoding)(struct _rfbClientRec* client, +			void** data, int encodingNumber); +	/* returns TRUE if message was handled */ +	rfbBool (*handleMessage)(struct _rfbClientRec* client, +				void* data, +				const rfbClientToServerMsg* message); +	void (*close)(struct _rfbClientRec* client, void* data); +	void (*usage)(void); +	/* processArguments returns the number of handled arguments */ +	int (*processArgument)(int argc, char *argv[]); +	struct _rfbProtocolExtension* next; +} rfbProtocolExtension; + +typedef struct _rfbExtensionData { +	rfbProtocolExtension* extension; +	void* data; +	struct _rfbExtensionData* next; +} rfbExtensionData; + +/* + * Per-screen (framebuffer) structure.  There can be as many as you wish, + * each serving different clients. However, you have to call + * rfbProcessEvents for each of these. + */ + +typedef struct _rfbScreenInfo +{ +    /* this structure has children that are scaled versions of this screen */ +    struct _rfbScreenInfo *scaledScreenNext; +    int scaledScreenRefCount; + +    int width; +    int paddedWidthInBytes; +    int height; +    int depth; +    int bitsPerPixel; +    int sizeInBytes; + +    rfbPixel blackPixel; +    rfbPixel whitePixel; + +    /* some screen specific data can be put into a struct where screenData +     * points to. You need this if you have more than one screen at the +     * same time while using the same functions. +     */ +    void* screenData; +   +    /* additions by libvncserver */ + +    rfbPixelFormat serverFormat; +    rfbColourMap colourMap; /* set this if rfbServerFormat.trueColour==FALSE */ +    const char* desktopName; +    char thisHost[255]; + +    rfbBool autoPort; +    int port; +    SOCKET listenSock; +    int maxSock; +    int maxFd; +#ifdef __MINGW32__ +    struct fd_set allFds; +#else +    fd_set allFds; +#endif + +    enum rfbSocketState socketState; +    SOCKET inetdSock; +    rfbBool inetdInitDone; + +    int udpPort; +    SOCKET udpSock; +    struct _rfbClientRec* udpClient; +    rfbBool udpSockConnected; +    struct sockaddr_in udpRemoteAddr; + +    int maxClientWait; + +    /* http stuff */ +    rfbBool httpInitDone; +    rfbBool httpEnableProxyConnect; +    int httpPort; +    char* httpDir; +    SOCKET httpListenSock; +    SOCKET httpSock; + +    rfbPasswordCheckProcPtr passwordCheck; +    void* authPasswdData; +    /* If rfbAuthPasswdData is given a list, this is the first +       view only password. */ +    int authPasswdFirstViewOnly; + +    /* send only this many rectangles in one update */ +    int maxRectsPerUpdate; +    /* this is the amount of milliseconds to wait at least before sending +     * an update. */ +    int deferUpdateTime; +#ifdef TODELETE +    char* screen; +#endif +    rfbBool alwaysShared; +    rfbBool neverShared; +    rfbBool dontDisconnect; +    struct _rfbClientRec* clientHead; +    struct _rfbClientRec* pointerClient;  /* "Mutex" for pointer events */ + + +    /* cursor */ +    int cursorX, cursorY,underCursorBufferLen; +    char* underCursorBuffer; +    rfbBool dontConvertRichCursorToXCursor; +    struct rfbCursor* cursor; + +    /* the frameBufferhas to be supplied by the serving process. +     * The buffer will not be freed by  +     */ +    char* frameBuffer; +    rfbKbdAddEventProcPtr kbdAddEvent; +    rfbKbdReleaseAllKeysProcPtr kbdReleaseAllKeys; +    rfbPtrAddEventProcPtr ptrAddEvent; +    rfbSetXCutTextProcPtr setXCutText; +    rfbGetCursorProcPtr getCursorPtr; +    rfbSetTranslateFunctionProcPtr setTranslateFunction; +    rfbSetSingleWindowProcPtr setSingleWindow; +    rfbSetServerInputProcPtr  setServerInput; +    rfbFileTransferPermitted  getFileTransferPermission; +    rfbSetTextChat            setTextChat; +     +    /* newClientHook is called just after a new client is created */ +    rfbNewClientHookPtr newClientHook; +    /* displayHook is called just before a frame buffer update */ +    rfbDisplayHookPtr displayHook; + +    /* These hooks are called to pass keyboard state back to the client */ +    rfbGetKeyboardLedStateHookPtr getKeyboardLedStateHook; + +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD +    MUTEX(cursorMutex); +    rfbBool backgroundLoop; +#endif + +    /* if TRUE, an ignoring signal handler is installed for SIGPIPE */ +    rfbBool ignoreSIGPIPE; + +    /* if not zero, only a slice of this height is processed every time +     * an update should be sent. This should make working on a slow +     * link more interactive. */ +    int progressiveSliceHeight; + +    in_addr_t listenInterface; +    int deferPtrUpdateTime; + +    /* handle as many input events as possible (default off) */ +    rfbBool handleEventsEagerly; + +    /* rfbEncodingServerIdentity */ +    char *versionString; + +    /* What does the server tell the new clients which version it supports */ +    int protocolMajorVersion; +    int protocolMinorVersion; + +    /* command line authorization of file transfers */ +    rfbBool permitFileTransfer; +} rfbScreenInfo, *rfbScreenInfoPtr; + + +/* + * rfbTranslateFnType is the type of translation functions. + */ + +typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in, +                                   rfbPixelFormat *out, +                                   char *iptr, char *optr, +                                   int bytesBetweenInputLines, +                                   int width, int height); + + +/* region stuff */ + +struct sraRegion; +typedef struct sraRegion* sraRegionPtr; + +/* + * Per-client structure. + */ + +typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl); + +typedef struct _rfbFileTransferData { +  int fd; +  int compressionEnabled; +  int fileSize; +  int numPackets; +  int receiving; +  int sending; +} rfbFileTransferData; + + +typedef struct _rfbStatList { +    uint32_t type; +    uint32_t sentCount; +    uint32_t bytesSent; +    uint32_t bytesSentIfRaw; +    uint32_t rcvdCount; +    uint32_t bytesRcvd; +    uint32_t bytesRcvdIfRaw; +    struct _rfbStatList *Next; +} rfbStatList; + +typedef struct _rfbClientRec { +   +    /* back pointer to the screen */ +    rfbScreenInfoPtr screen; + +     /* points to a scaled version of the screen buffer in cl->scaledScreenList */ +     rfbScreenInfoPtr scaledScreen; +     /* how did the client tell us it wanted the screen changed?  Ultra style or palm style? */ +     rfbBool PalmVNC; +     +   +    /* private data. You should put any application client specific data +     * into a struct and let clientData point to it. Don't forget to +     * free the struct via clientGoneHook! +     * +     * This is useful if the IO functions have to behave client specific. +     */ +    void* clientData; +    ClientGoneHookPtr clientGoneHook; + +    SOCKET sock; +    char *host; + +    /* RFB protocol minor version number */ +    int protocolMajorVersion; +    int protocolMinorVersion; + +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD +    pthread_t client_thread; +#endif +                                /* Possible client states: */ +    enum { +        RFB_PROTOCOL_VERSION,   /* establishing protocol version */ +	RFB_SECURITY_TYPE,      /* negotiating security (RFB v.3.7) */ +        RFB_AUTHENTICATION,     /* authenticating */ +        RFB_INITIALISATION,     /* sending initialisation messages */ +        RFB_NORMAL              /* normal protocol messages */ +    } state; + +    rfbBool reverseConnection; +    rfbBool onHold; +    rfbBool readyForSetColourMapEntries; +    rfbBool useCopyRect; +    int preferredEncoding; +    int correMaxWidth, correMaxHeight; + +    rfbBool viewOnly; + +    /* The following member is only used during VNC authentication */ +    uint8_t authChallenge[CHALLENGESIZE]; + +    /* The following members represent the update needed to get the client's +       framebuffer from its present state to the current state of our +       framebuffer. + +       If the client does not accept CopyRect encoding then the update is +       simply represented as the region of the screen which has been modified +       (modifiedRegion). + +       If the client does accept CopyRect encoding, then the update consists of +       two parts.  First we have a single copy from one region of the screen to +       another (the destination of the copy is copyRegion), and second we have +       the region of the screen which has been modified in some other way +       (modifiedRegion). + +       Although the copy is of a single region, this region may have many +       rectangles.  When sending an update, the copyRegion is always sent +       before the modifiedRegion.  This is because the modifiedRegion may +       overlap parts of the screen which are in the source of the copy. + +       In fact during normal processing, the modifiedRegion may even overlap +       the destination copyRegion.  Just before an update is sent we remove +       from the copyRegion anything in the modifiedRegion. */ + +    sraRegionPtr copyRegion;	/* the destination region of the copy */ +    int copyDX, copyDY;		/* the translation by which the copy happens */ + +    sraRegionPtr modifiedRegion; + +    /* As part of the FramebufferUpdateRequest, a client can express interest +       in a subrectangle of the whole framebuffer.  This is stored in the +       requestedRegion member.  In the normal case this is the whole +       framebuffer if the client is ready, empty if it's not. */ + +    sraRegionPtr requestedRegion; + +    /* The following member represents the state of the "deferred update" timer +       - when the framebuffer is modified and the client is ready, in most +       cases it is more efficient to defer sending the update by a few +       milliseconds so that several changes to the framebuffer can be combined +       into a single update. */ + +      struct timeval startDeferring; +      struct timeval startPtrDeferring; +      int lastPtrX; +      int lastPtrY; +      int lastPtrButtons; + +    /* translateFn points to the translation function which is used to copy +       and translate a rectangle from the framebuffer to an output buffer. */ + +    rfbTranslateFnType translateFn; +    char *translateLookupTable; +    rfbPixelFormat format; + +    /* +     * UPDATE_BUF_SIZE must be big enough to send at least one whole line of the +     * framebuffer.  So for a max screen width of say 2K with 32-bit pixels this +     * means 8K minimum. +     */ + +#define UPDATE_BUF_SIZE 30000 + +    char updateBuf[UPDATE_BUF_SIZE]; +    int ublen; + +    /* statistics */ +    struct _rfbStatList *statEncList; +    struct _rfbStatList *statMsgList; +    int rawBytesEquivalent; +    int bytesSent; +         +#ifdef LIBVNCSERVER_HAVE_LIBZ +    /* zlib encoding -- necessary compression state info per client */ + +    struct z_stream_s compStream; +    rfbBool compStreamInited; +    uint32_t zlibCompressLevel; +    /* the quality level is also used by ZYWRLE */ +    int tightQualityLevel; + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +    /* tight encoding -- preserve zlib streams' state for each client */ +    z_stream zsStruct[4]; +    rfbBool zsActive[4]; +    int zsLevel[4]; +    int tightCompressLevel; +#endif +#endif + +    /* Ultra Encoding support */ +    rfbBool compStreamInitedLZO; +    char *lzoWrkMem; + +    rfbFileTransferData fileTransfer; + +    int     lastKeyboardLedState;     /* keep track of last value so we can send *change* events */ +    rfbBool enableSupportedMessages;  /* client supports SupportedMessages encoding */ +    rfbBool enableSupportedEncodings; /* client supports SupportedEncodings encoding */ +    rfbBool enableServerIdentity;     /* client supports ServerIdentity encoding */ +    rfbBool enableKeyboardLedState;   /* client supports KeyboardState encoding */ +    rfbBool enableLastRectEncoding;   /* client supports LastRect encoding */ +    rfbBool enableCursorShapeUpdates; /* client supports cursor shape updates */ +    rfbBool enableCursorPosUpdates;   /* client supports cursor position updates */ +    rfbBool useRichCursorEncoding;    /* rfbEncodingRichCursor is preferred */ +    rfbBool cursorWasChanged;         /* cursor shape update should be sent */ +    rfbBool cursorWasMoved;           /* cursor position update should be sent */ +    int cursorX,cursorY;	      /* the coordinates of the cursor, +					 if enableCursorShapeUpdates = FALSE */ + +    rfbBool useNewFBSize;             /* client supports NewFBSize encoding */ +    rfbBool newFBSizePending;         /* framebuffer size was changed */ + +    struct _rfbClientRec *prev; +    struct _rfbClientRec *next; + +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD +    /* whenever a client is referenced, the refCount has to be incremented +       and afterwards decremented, so that the client is not cleaned up +       while being referenced. +       Use the functions rfbIncrClientRef(cl) and rfbDecrClientRef(cl); +    */ +    int refCount; +    MUTEX(refCountMutex); +    COND(deleteCond); + +    MUTEX(outputMutex); +    MUTEX(updateMutex); +    COND(updateCond); +#endif + +#ifdef LIBVNCSERVER_HAVE_LIBZ +    void* zrleData; +    int zywrleLevel; +    int zywrleBuf[rfbZRLETileWidth * rfbZRLETileHeight]; +#endif + +    /* if progressive updating is on, this variable holds the current +     * y coordinate of the progressive slice. */ +    int progressiveSliceY; + +    rfbExtensionData* extensions; + +    /* for threaded zrle */ +    char *zrleBeforeBuf; +    void *paletteHelper; + +    /* for thread safety for rfbSendFBUpdate() */ +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD +#define LIBVNCSERVER_SEND_MUTEX +    MUTEX(sendMutex); +#endif + +} rfbClientRec, *rfbClientPtr; + +/* + * This macro is used to test whether there is a framebuffer update needing to + * be sent to the client. + */ + +#define FB_UPDATE_PENDING(cl)                                              \ +     (((cl)->enableCursorShapeUpdates && (cl)->cursorWasChanged) ||        \ +     (((cl)->enableCursorShapeUpdates == FALSE &&                          \ +       ((cl)->cursorX != (cl)->screen->cursorX ||                          \ +	(cl)->cursorY != (cl)->screen->cursorY))) ||                       \ +     ((cl)->useNewFBSize && (cl)->newFBSizePending) ||                     \ +     ((cl)->enableCursorPosUpdates && (cl)->cursorWasMoved) ||             \ +     !sraRgnEmpty((cl)->copyRegion) || !sraRgnEmpty((cl)->modifiedRegion)) + +/* + * Macros for endian swapping. + */ + +#define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) + +#define Swap24(l) ((((l) & 0xff) << 16) | (((l) >> 16) & 0xff) | \ +                   (((l) & 0x00ff00))) + +#define Swap32(l) (((l) >> 24) | \ +                   (((l) & 0x00ff0000) >> 8)  | \ +                   (((l) & 0x0000ff00) << 8)  | \ +                   ((l) << 24)) + + +extern char rfbEndianTest; + +#define Swap16IfLE(s) (rfbEndianTest ? Swap16(s) : (s)) +#define Swap24IfLE(l) (rfbEndianTest ? Swap24(l) : (l)) +#define Swap32IfLE(l) (rfbEndianTest ? Swap32(l) : (l)) + +/* UltraVNC uses some windows structures unmodified, so the viewer expects LittleEndian Data */ +#define Swap16IfBE(s) (rfbEndianTest ? (s) : Swap16(s)) +#define Swap24IfBE(l) (rfbEndianTest ? (l) : Swap24(l)) +#define Swap32IfBE(l) (rfbEndianTest ? (l) : Swap32(l)) + +/* sockets.c */ + +extern int rfbMaxClientWait; + +extern void rfbInitSockets(rfbScreenInfoPtr rfbScreen); +extern void rfbShutdownSockets(rfbScreenInfoPtr rfbScreen); +extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen); +extern void rfbCloseClient(rfbClientPtr cl); +extern int rfbReadExact(rfbClientPtr cl, char *buf, int len); +extern int rfbReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout); +extern int rfbWriteExact(rfbClientPtr cl, const char *buf, int len); +extern int rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec); +extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port); +extern int rfbConnectToTcpAddr(char* host, int port); +extern int rfbListenOnTCPPort(int port, in_addr_t iface); +extern int rfbListenOnUDPPort(int port, in_addr_t iface); +extern int rfbStringToAddr(char* string,in_addr_t* addr); + +/* rfbserver.c */ + +/* Routines to iterate over the client list in a thread-safe way. +   Only a single iterator can be in use at a time process-wide. */ +typedef struct rfbClientIterator *rfbClientIteratorPtr; + +extern void rfbClientListInit(rfbScreenInfoPtr rfbScreen); +extern rfbClientIteratorPtr rfbGetClientIterator(rfbScreenInfoPtr rfbScreen); +extern rfbClientPtr rfbClientIteratorNext(rfbClientIteratorPtr iterator); +extern void rfbReleaseClientIterator(rfbClientIteratorPtr iterator); +extern void rfbIncrClientRef(rfbClientPtr cl); +extern void rfbDecrClientRef(rfbClientPtr cl); + +extern void rfbNewClientConnection(rfbScreenInfoPtr rfbScreen,int sock); +extern rfbClientPtr rfbNewClient(rfbScreenInfoPtr rfbScreen,int sock); +extern rfbClientPtr rfbNewUDPClient(rfbScreenInfoPtr rfbScreen); +extern rfbClientPtr rfbReverseConnection(rfbScreenInfoPtr rfbScreen,char *host, int port); +extern void rfbClientConnectionGone(rfbClientPtr cl); +extern void rfbProcessClientMessage(rfbClientPtr cl); +extern void rfbClientConnFailed(rfbClientPtr cl, char *reason); +extern void rfbNewUDPConnection(rfbScreenInfoPtr rfbScreen,int sock); +extern void rfbProcessUDPInput(rfbScreenInfoPtr rfbScreen); +extern rfbBool rfbSendFramebufferUpdate(rfbClientPtr cl, sraRegionPtr updateRegion); +extern rfbBool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h); +extern rfbBool rfbSendUpdateBuf(rfbClientPtr cl); +extern void rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len); +extern rfbBool rfbSendCopyRegion(rfbClientPtr cl,sraRegionPtr reg,int dx,int dy); +extern rfbBool rfbSendLastRectMarker(rfbClientPtr cl); +extern rfbBool rfbSendNewFBSize(rfbClientPtr cl, int w, int h); +extern rfbBool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, int nColours); +extern void rfbSendBell(rfbScreenInfoPtr rfbScreen); + +extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length); +extern rfbBool rfbSendFileTransferChunk(rfbClientPtr cl); +extern rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer); +extern rfbBool rfbSendFileTransferMessage(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length, char *buffer); +extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length); +extern rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length); + +void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len); + +/* translate.c */ + +extern rfbBool rfbEconomicTranslate; + +extern void rfbTranslateNone(char *table, rfbPixelFormat *in, +                             rfbPixelFormat *out, +                             char *iptr, char *optr, +                             int bytesBetweenInputLines, +                             int width, int height); +extern rfbBool rfbSetTranslateFunction(rfbClientPtr cl); +extern rfbBool rfbSetClientColourMap(rfbClientPtr cl, int firstColour, int nColours); +extern void rfbSetClientColourMaps(rfbScreenInfoPtr rfbScreen, int firstColour, int nColours); + +/* httpd.c */ + +extern void rfbHttpInitSockets(rfbScreenInfoPtr rfbScreen); +extern void rfbHttpShutdownSockets(rfbScreenInfoPtr rfbScreen); +extern void rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen); + + + +/* auth.c */ + +extern void rfbAuthNewClient(rfbClientPtr cl); +extern void rfbProcessClientSecurityType(rfbClientPtr cl); +extern void rfbAuthProcessClientMessage(rfbClientPtr cl); +extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler); +extern void rfbUnregisterSecurityHandler(rfbSecurityHandler* handler); + +/* rre.c */ + +extern rfbBool rfbSendRectEncodingRRE(rfbClientPtr cl, int x,int y,int w,int h); + + +/* corre.c */ + +extern rfbBool rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x,int y,int w,int h); + + +/* hextile.c */ + +extern rfbBool rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w, +                                       int h); + +/* ultra.c */ + +/* Set maximum ultra rectangle size in pixels.  Always allow at least + * two scan lines. + */ +#define ULTRA_MAX_RECT_SIZE (128*256) +#define ULTRA_MAX_SIZE(min) ((( min * 2 ) > ULTRA_MAX_RECT_SIZE ) ? \ +                            ( min * 2 ) : ULTRA_MAX_RECT_SIZE ) + +extern rfbBool rfbSendRectEncodingUltra(rfbClientPtr cl, int x,int y,int w,int h); + + +#ifdef LIBVNCSERVER_HAVE_LIBZ +/* zlib.c */ + +/* Minimum zlib rectangle size in bytes.  Anything smaller will + * not compress well due to overhead. + */ +#define VNC_ENCODE_ZLIB_MIN_COMP_SIZE (17) + +/* Set maximum zlib rectangle size in pixels.  Always allow at least + * two scan lines. + */ +#define ZLIB_MAX_RECT_SIZE (128*256) +#define ZLIB_MAX_SIZE(min) ((( min * 2 ) > ZLIB_MAX_RECT_SIZE ) ? \ +			    ( min * 2 ) : ZLIB_MAX_RECT_SIZE ) + +extern rfbBool rfbSendRectEncodingZlib(rfbClientPtr cl, int x, int y, int w, +				    int h); + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +/* tight.c */ + +#define TIGHT_DEFAULT_COMPRESSION  6 + +extern rfbBool rfbTightDisableGradient; + +extern int rfbNumCodedRectsTight(rfbClientPtr cl, int x,int y,int w,int h); +extern rfbBool rfbSendRectEncodingTight(rfbClientPtr cl, int x,int y,int w,int h); + +#endif +#endif + + +/* cursor.c */ + +typedef struct rfbCursor { +    /* set this to true if LibVNCServer has to free this cursor */ +    rfbBool cleanup, cleanupSource, cleanupMask, cleanupRichSource; +    unsigned char *source;			/* points to bits */ +    unsigned char *mask;			/* points to bits */ +    unsigned short width, height, xhot, yhot;	/* metrics */ +    unsigned short foreRed, foreGreen, foreBlue; /* device-independent colour */ +    unsigned short backRed, backGreen, backBlue; /* device-independent colour */ +    unsigned char *richSource; /* source bytes for a rich cursor */ +    unsigned char *alphaSource; /* source for alpha blending info */ +    rfbBool alphaPreMultiplied; /* if richSource already has alpha applied */ +} rfbCursor, *rfbCursorPtr; +extern unsigned char rfbReverseByte[0x100]; + +extern rfbBool rfbSendCursorShape(rfbClientPtr cl/*, rfbScreenInfoPtr pScreen*/); +extern rfbBool rfbSendCursorPos(rfbClientPtr cl); +extern void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap); +extern rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskString); +extern char* rfbMakeMaskForXCursor(int width,int height,char* cursorString); +extern char* rfbMakeMaskFromAlphaSource(int width,int height,unsigned char* alphaSource); +extern void rfbMakeXCursorFromRichCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor); +extern void rfbMakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor); +extern void rfbFreeCursor(rfbCursorPtr cursor); +extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c); + +/* cursor handling for the pointer */ +extern void rfbDefaultPtrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl); + +/* zrle.c */ +#ifdef LIBVNCSERVER_HAVE_LIBZ +extern rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,int h); +#endif + +/* stats.c */ + +extern void rfbResetStats(rfbClientPtr cl); +extern void rfbPrintStats(rfbClientPtr cl); + +/* font.c */ + +typedef struct rfbFontData { +  unsigned char* data; +  /* +    metaData is a 256*5 array: +    for each character +    (offset,width,height,x,y) +  */ +  int* metaData; +} rfbFontData,* rfbFontDataPtr; + +int rfbDrawChar(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,rfbPixel colour); +void rfbDrawString(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,rfbPixel colour); +/* if colour==backColour, background is transparent */ +int rfbDrawCharWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,int x1,int y1,int x2,int y2,rfbPixel colour,rfbPixel backColour); +void rfbDrawStringWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,int x1,int y1,int x2,int y2,rfbPixel colour,rfbPixel backColour); +int rfbWidthOfString(rfbFontDataPtr font,const char* string); +int rfbWidthOfChar(rfbFontDataPtr font,unsigned char c); +void rfbFontBBox(rfbFontDataPtr font,unsigned char c,int* x1,int* y1,int* x2,int* y2); +/* this returns the smallest box enclosing any character of font. */ +void rfbWholeFontBBox(rfbFontDataPtr font,int *x1, int *y1, int *x2, int *y2); + +/* dynamically load a linux console font (4096 bytes, 256 glyphs a 8x16 */ +rfbFontDataPtr rfbLoadConsoleFont(char *filename); +/* free a dynamically loaded font */ +void rfbFreeFont(rfbFontDataPtr font); + +/* draw.c */ + +void rfbFillRect(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col); +void rfbDrawPixel(rfbScreenInfoPtr s,int x,int y,rfbPixel col); +void rfbDrawLine(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col); + +/* selbox.c */ + +/* this opens a modal select box. list is an array of strings, the end marked +   with a NULL. +   It returns the index in the list or -1 if cancelled or something else +   wasn't kosher. */ +typedef void (*SelectionChangedHookPtr)(int _index); +extern int rfbSelectBox(rfbScreenInfoPtr rfbScreen, +			rfbFontDataPtr font, char** list, +			int x1, int y1, int x2, int y2, +			rfbPixel foreColour, rfbPixel backColour, +			int border,SelectionChangedHookPtr selChangedHook); + +/* cargs.c */ + +extern void rfbUsage(void); +extern void rfbPurgeArguments(int* argc,int* position,int count,char *argv[]); +extern rfbBool rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[]); +extern rfbBool rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[]); + +/* main.c */ + +extern void rfbLogEnable(int enabled); +typedef void (*rfbLogProc)(const char *format, ...); +extern rfbLogProc rfbLog, rfbErr; +extern void rfbLogPerror(const char *str); + +void rfbScheduleCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy); +void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy); + +void rfbDoCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy); +void rfbDoCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy); + +void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2); +void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion); +void rfbDoNothingWithClient(rfbClientPtr cl); +enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl); +void rfbRegisterProtocolExtension(rfbProtocolExtension* extension); +void rfbUnregisterProtocolExtension(rfbProtocolExtension* extension); +struct _rfbProtocolExtension* rfbGetExtensionIterator(); +void rfbReleaseExtensionIterator(); +rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension, +	void* data); +rfbBool rfbDisableExtension(rfbClientPtr cl, rfbProtocolExtension* extension); +void* rfbGetExtensionClientData(rfbClientPtr cl, rfbProtocolExtension* extension); + +/* to check against plain passwords */ +rfbBool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len); + +/* functions to make a vnc server */ +extern rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv, + int width,int height,int bitsPerSample,int samplesPerPixel, + int bytesPerPixel); +extern void rfbInitServer(rfbScreenInfoPtr rfbScreen); +extern void rfbShutdownServer(rfbScreenInfoPtr rfbScreen,rfbBool disconnectClients); +extern void rfbNewFramebuffer(rfbScreenInfoPtr rfbScreen,char *framebuffer, + int width,int height, int bitsPerSample,int samplesPerPixel, + int bytesPerPixel); + +extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo); +extern void rfbSetServerVersionIdentity(rfbScreenInfoPtr screen, char *fmt, ...); + +/* functions to accept/refuse a client that has been put on hold +   by a NewClientHookPtr function. Must not be called in other +   situations. */ +extern void rfbStartOnHoldClient(rfbClientPtr cl); +extern void rfbRefuseOnHoldClient(rfbClientPtr cl); + +/* call one of these two functions to service the vnc clients. + usec are the microseconds the select on the fds waits. + if you are using the event loop, set this to some value > 0, so the + server doesn't get a high load just by listening. + rfbProcessEvents() returns TRUE if an update was pending. */ + +extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, rfbBool runInBackground); +extern rfbBool rfbProcessEvents(rfbScreenInfoPtr screenInfo,long usec); +extern rfbBool rfbIsActive(rfbScreenInfoPtr screenInfo); + +/* TightVNC file transfer extension */ +void rfbRegisterTightVNCFileTransferExtension(); +void rfbUnregisterTightVNCFileTransferExtension();  + +/* Statistics */ +extern char *messageNameServer2Client(uint32_t type, char *buf, int len); +extern char *messageNameClient2Server(uint32_t type, char *buf, int len); +extern char *encodingName(uint32_t enc, char *buf, int len); + +extern rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type); +extern rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type); + +/* Each call to rfbStatRecord* adds one to the rect count for that type */ +extern void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw); +extern void rfbStatRecordEncodingSentAdd(rfbClientPtr cl, uint32_t type, int byteCount); /* Specifically for tight encoding */ +extern void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw); +extern void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw); +extern void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw); +extern void rfbResetStats(rfbClientPtr cl); +extern void rfbPrintStats(rfbClientPtr cl); + +extern int rfbStatGetSentBytes(rfbClientPtr cl); +extern int rfbStatGetSentBytesIfRaw(rfbClientPtr cl); +extern int rfbStatGetRcvdBytes(rfbClientPtr cl); +extern int rfbStatGetRcvdBytesIfRaw(rfbClientPtr cl); +extern int rfbStatGetMessageCountSent(rfbClientPtr cl, uint32_t type); +extern int rfbStatGetMessageCountRcvd(rfbClientPtr cl, uint32_t type); +extern int rfbStatGetEncodingCountSent(rfbClientPtr cl, uint32_t type); +extern int rfbStatGetEncodingCountRcvd(rfbClientPtr cl, uint32_t type); + +/* Set which version you want to advertise 3.3, 3.6, 3.7 and 3.8 are currently supported*/ +extern void rfbSetProtocolVersion(rfbScreenInfoPtr rfbScreen, int major_, int minor_); + +/* send a TextChat message to a client */ +extern rfbBool rfbSendTextChatMessage(rfbClientPtr cl, uint32_t length, char *buffer); + + + + +#if(defined __cplusplus) +} +#endif + +#endif + diff --git a/3rdParty/LibVNC/src/rfb/rfbclient.h b/3rdParty/LibVNC/src/rfb/rfbclient.h new file mode 100644 index 0000000..bc4ec14 --- /dev/null +++ b/3rdParty/LibVNC/src/rfb/rfbclient.h @@ -0,0 +1,406 @@ +#ifndef RFBCLIENT_H +#define RFBCLIENT_H + +/* + *  Copyright (C) 2000, 2001 Const Kaplinsky.  All Rights Reserved. + *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved. + *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved. + * + *  This is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This software is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this software; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, + *  USA. + */ + +/* + * vncviewer.h + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/time.h> +#include <unistd.h> +#include <rfb/rfbproto.h> +#include <rfb/keysym.h> +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +#include <gnutls/gnutls.h> +#endif + +#define rfbClientSwap16IfLE(s) \ +    (*(char *)&client->endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s)) + +#define rfbClientSwap32IfLE(l) \ +    (*(char *)&client->endianTest ? ((((l) & 0xff000000) >> 24) | \ +			     (((l) & 0x00ff0000) >> 8)  | \ +			     (((l) & 0x0000ff00) << 8)  | \ +			     (((l) & 0x000000ff) << 24))  : (l)) + +#define rfbClientSwap64IfLE(l) \ +    (*(char *)&client->endianTest ? ((((l) & 0xff00000000000000ULL) >> 56) | \ +			     (((l) & 0x00ff000000000000ULL) >> 40)  | \ +			     (((l) & 0x0000ff0000000000ULL) >> 24)  | \ +			     (((l) & 0x000000ff00000000ULL) >> 8)  | \ +			     (((l) & 0x00000000ff000000ULL) << 8)  | \ +			     (((l) & 0x0000000000ff0000ULL) << 24)  | \ +			     (((l) & 0x000000000000ff00ULL) << 40)  | \ +			     (((l) & 0x00000000000000ffULL) << 56))  : (l)) + +#define FLASH_PORT_OFFSET 5400 +#define LISTEN_PORT_OFFSET 5500 +#define TUNNEL_PORT_OFFSET 5500 +#define SERVER_PORT_OFFSET 5900 + +#define DEFAULT_SSH_CMD "/usr/bin/ssh" +#define DEFAULT_TUNNEL_CMD  \ +  (DEFAULT_SSH_CMD " -f -L %L:localhost:%R %H sleep 20") +#define DEFAULT_VIA_CMD     \ +  (DEFAULT_SSH_CMD " -f -L %L:%H:%R %G sleep 20") + +#if(defined __cplusplus) +extern "C" +{ +#endif + +/* vncrec */ + +typedef struct { +  FILE* file; +  struct timeval tv; +  rfbBool readTimestamp; +  rfbBool doNotSleep; +} rfbVNCRec; + +/* client data */ + +typedef struct rfbClientData { +	void* tag; +	void* data; +	struct rfbClientData* next; +} rfbClientData; + +/* app data (belongs into rfbClient?) */ + +typedef struct { +  rfbBool shareDesktop; +  rfbBool viewOnly; + +  const char* encodingsString; + +  rfbBool useBGR233; +  int nColours; +  rfbBool forceOwnCmap; +  rfbBool forceTrueColour; +  int requestedDepth; + +  int compressLevel; +  int qualityLevel; +  rfbBool enableJPEG; +  rfbBool useRemoteCursor; +  rfbBool palmVNC;  /* use palmvnc specific SetScale (vs ultravnc) */ +  int scaleSetting; /* 0 means no scale set, else 1/scaleSetting */ +} AppData; + +/* For GetCredentialProc callback function to return */ +typedef union _rfbCredential +{ +  /* X509 (VeNCrypt) */ +  struct +  { +    char *x509CACertFile; +    char *x509CACrlFile; +    char *x509ClientCertFile; +    char *x509ClientKeyFile; +  } x509Credential; +  /* Plain (VeNCrypt), MSLogon (UltraVNC) */ +  struct +  { +    char *username; +    char *password; +  } userCredential; +} rfbCredential; + +#define rfbCredentialTypeX509 1 +#define rfbCredentialTypeUser 2 + +struct _rfbClient; + +typedef void (*HandleTextChatProc)(struct _rfbClient* client, int value, char *text); +typedef void (*HandleKeyboardLedStateProc)(struct _rfbClient* client, int value, int pad); +typedef rfbBool (*HandleCursorPosProc)(struct _rfbClient* client, int x, int y); +typedef void (*SoftCursorLockAreaProc)(struct _rfbClient* client, int x, int y, int w, int h); +typedef void (*SoftCursorUnlockScreenProc)(struct _rfbClient* client); +typedef void (*GotFrameBufferUpdateProc)(struct _rfbClient* client, int x, int y, int w, int h); +typedef void (*FinishedFrameBufferUpdateProc)(struct _rfbClient* client); +typedef char* (*GetPasswordProc)(struct _rfbClient* client); +typedef rfbCredential* (*GetCredentialProc)(struct _rfbClient* client, int credentialType); +typedef rfbBool (*MallocFrameBufferProc)(struct _rfbClient* client); +typedef void (*GotXCutTextProc)(struct _rfbClient* client, const char *text, int textlen); +typedef void (*BellProc)(struct _rfbClient* client); + +typedef void (*GotCursorShapeProc)(struct _rfbClient* client, int xhot, int yhot, int width, int height, int bytesPerPixel); +typedef void (*GotCopyRectProc)(struct _rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y); + +typedef struct _rfbClient { +	uint8_t* frameBuffer; +	int width, height; + +	int endianTest; + +	AppData appData; + +	const char* programName; +	char* serverHost; +	int serverPort; /* if -1, then use file recorded by vncrec */ +	rfbBool listenSpecified; +	int listenPort, flashPort; + +	struct { +		int x, y, w, h; +	} updateRect; + +	/* Note that the CoRRE encoding uses this buffer and assumes it is big enough +	   to hold 255 * 255 * 32 bits -> 260100 bytes.  640*480 = 307200 bytes. +	   Hextile also assumes it is big enough to hold 16 * 16 * 32 bits. +	   Tight encoding assumes BUFFER_SIZE is at least 16384 bytes. */ + +#define RFB_BUFFER_SIZE (640*480) +	char buffer[RFB_BUFFER_SIZE]; + +	/* rfbproto.c */ + +	int sock; +	rfbBool canUseCoRRE; +	rfbBool canUseHextile; +	char *desktopName; +	rfbPixelFormat format; +	rfbServerInitMsg si; + +	/* listen.c */ +        int listenSock; + +	/* sockets.c */ +#define RFB_BUF_SIZE 8192 +	char buf[RFB_BUF_SIZE]; +	char *bufoutptr; +	int buffered; + +	/* The zlib encoding requires expansion/decompression/deflation of the +	   compressed data in the "buffer" above into another, result buffer. +	   However, the size of the result buffer can be determined precisely +	   based on the bitsPerPixel, height and width of the rectangle.  We +	   allocate this buffer one time to be the full size of the buffer. */ + +	/* Ultra Encoding uses this buffer too */ +	 +	int ultra_buffer_size; +	char *ultra_buffer; + +	int raw_buffer_size; +	char *raw_buffer; + +#ifdef LIBVNCSERVER_HAVE_LIBZ +	z_stream decompStream; +	rfbBool decompStreamInited; +#endif + + +#ifdef LIBVNCSERVER_HAVE_LIBZ +	/* +	 * Variables for the ``tight'' encoding implementation. +	 */ + +	/* Separate buffer for compressed data. */ +#define ZLIB_BUFFER_SIZE 30000 +	char zlib_buffer[ZLIB_BUFFER_SIZE]; + +	/* Four independent compression streams for zlib library. */ +	z_stream zlibStream[4]; +	rfbBool zlibStreamActive[4]; + +	/* Filter stuff. Should be initialized by filter initialization code. */ +	rfbBool cutZeros; +	int rectWidth, rectColors; +	char tightPalette[256*4]; +	uint8_t tightPrevRow[2048*3*sizeof(uint16_t)]; + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +	/* JPEG decoder state. */ +	rfbBool jpegError; + +	struct jpeg_source_mgr* jpegSrcManager; +	void* jpegBufferPtr; +	size_t jpegBufferLen; + +#endif +#endif + + +	/* cursor.c */ +	uint8_t *rcSource, *rcMask; + +	/* private data pointer */ +	rfbClientData* clientData; + +	rfbVNCRec* vncRec; + +	/* Keyboard State support (is 'Caps Lock' set on the remote display???) */ +	int KeyboardLedStateEnabled; +	int CurrentKeyboardLedState; + +	int canHandleNewFBSize; + +	/* hooks */ +	HandleTextChatProc         HandleTextChat; +	HandleKeyboardLedStateProc HandleKeyboardLedState; +	HandleCursorPosProc HandleCursorPos; +	SoftCursorLockAreaProc SoftCursorLockArea; +	SoftCursorUnlockScreenProc SoftCursorUnlockScreen; +	GotFrameBufferUpdateProc GotFrameBufferUpdate; +	FinishedFrameBufferUpdateProc FinishedFrameBufferUpdate; +	/* the pointer returned by GetPassword will be freed after use! */ +	GetPasswordProc GetPassword; +	MallocFrameBufferProc MallocFrameBuffer; +	GotXCutTextProc GotXCutText; +	BellProc Bell; + +	GotCursorShapeProc GotCursorShape; +	GotCopyRectProc GotCopyRect; + +	/* Which messages are supported by the server +	 * This is a *guess* for most servers. +	 * (If we can even detect the type of server) +	 * +	 * If the server supports the "rfbEncodingSupportedMessages" +	 * then this will be updated when the encoding is received to +	 * accurately reflect the servers capabilities. +	 */ +	rfbSupportedMessages supportedMessages; + +	/* negotiated protocol version */ +	int major, minor; + +	/* The selected security types */ +	uint32_t authScheme, subAuthScheme; + +#ifdef LIBVNCSERVER_WITH_CLIENT_TLS +	/* The TLS session for Anonymous TLS and VeNCrypt */ +	gnutls_session_t tlsSession; +#endif + +	/* To support security types that requires user input (except VNC password +	 * authentication), for example VeNCrypt and MSLogon, this callback function +	 * must be set before the authentication. Otherwise, it implicates that the +	 * caller application does not support it and related security types should +	 * be bypassed. +	 */ +	GetCredentialProc GetCredential; + +	/* The 0-terminated security types supported by the client. +	 * Set by function SetClientAuthSchemes() */ +	uint32_t *clientAuthSchemes; + +	/* When the server is a repeater, this specifies the final destination */ +	char *destHost; +	int destPort; +} rfbClient; + +/* cursor.c */ + +extern rfbBool HandleCursorShape(rfbClient* client,int xhot, int yhot, int width, int height, uint32_t enc); + +/* listen.c */ + +extern void listenForIncomingConnections(rfbClient* viewer); +extern int listenForIncomingConnectionsNoFork(rfbClient* viewer, int usec_timeout); + +/* rfbproto.c */ + +extern rfbBool rfbEnableClientLogging; +typedef void (*rfbClientLogProc)(const char *format, ...); +extern rfbClientLogProc rfbClientLog,rfbClientErr; +extern rfbBool ConnectToRFBServer(rfbClient* client,const char *hostname, int port); +extern rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort); +extern void SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size); +extern rfbBool InitialiseRFBConnection(rfbClient* client); +extern rfbBool SetFormatAndEncodings(rfbClient* client); +extern rfbBool SendIncrementalFramebufferUpdateRequest(rfbClient* client); +extern rfbBool SendFramebufferUpdateRequest(rfbClient* client, +					 int x, int y, int w, int h, +					 rfbBool incremental); +extern rfbBool SendScaleSetting(rfbClient* client,int scaleSetting); +extern rfbBool SendPointerEvent(rfbClient* client,int x, int y, int buttonMask); +extern rfbBool SendKeyEvent(rfbClient* client,uint32_t key, rfbBool down); +extern rfbBool SendClientCutText(rfbClient* client,char *str, int len); +extern rfbBool HandleRFBServerMessage(rfbClient* client); + +extern rfbBool TextChatSend(rfbClient* client, char *text); +extern rfbBool TextChatOpen(rfbClient* client); +extern rfbBool TextChatClose(rfbClient* client); +extern rfbBool TextChatFinish(rfbClient* client); +extern rfbBool PermitServerInput(rfbClient* client, int enabled); + +extern void PrintPixelFormat(rfbPixelFormat *format); + +extern rfbBool SupportsClient2Server(rfbClient* client, int messageType); +extern rfbBool SupportsServer2Client(rfbClient* client, int messageType); + +/* client data */ + +void rfbClientSetClientData(rfbClient* client, void* tag, void* data); +void* rfbClientGetClientData(rfbClient* client, void* tag); + +/* protocol extensions */ + +typedef struct _rfbClientProtocolExtension { +	int* encodings; +	/* returns TRUE if the encoding was handled */ +	rfbBool (*handleEncoding)(rfbClient* cl, +		rfbFramebufferUpdateRectHeader* rect); +	/* returns TRUE if it handled the message */ +	rfbBool (*handleMessage)(rfbClient* cl, +		 rfbServerToClientMsg* message); +	struct _rfbClientProtocolExtension* next; +} rfbClientProtocolExtension; + +void rfbClientRegisterExtension(rfbClientProtocolExtension* e); + +/* sockets.c */ + +extern rfbBool errorMessageOnReadFailure; + +extern rfbBool ReadFromRFBServer(rfbClient* client, char *out, unsigned int n); +extern rfbBool WriteToRFBServer(rfbClient* client, char *buf, int n); +extern int FindFreeTcpPort(void); +extern int ListenAtTcpPort(int port); +extern int ConnectClientToTcpAddr(unsigned int host, int port); +extern int ConnectClientToUnixSock(const char *sockFile); +extern int AcceptTcpConnection(int listenSock); +extern rfbBool SetNonBlocking(int sock); + +extern rfbBool StringToIPAddr(const char *str, unsigned int *addr); +extern rfbBool SameMachine(int sock); +extern int WaitForMessage(rfbClient* client,unsigned int usecs); + +/* vncviewer.c */ +rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,int bytesPerPixel); +rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv); +/* rfbClientCleanup() does not touch client->frameBuffer */ +void rfbClientCleanup(rfbClient* client); + +#if(defined __cplusplus) +} +#endif + +#endif + diff --git a/3rdParty/LibVNC/src/rfb/rfbconfig.h b/3rdParty/LibVNC/src/rfb/rfbconfig.h new file mode 100644 index 0000000..1d06196 --- /dev/null +++ b/3rdParty/LibVNC/src/rfb/rfbconfig.h @@ -0,0 +1,557 @@ +#ifndef _RFB_RFBCONFIG_H +#define _RFB_RFBCONFIG_H 1 +  +/* rfb/rfbconfig.h. Generated automatically at end of configure. */ +/* rfbconfig.h.  Generated by configure.  */ +/* rfbconfig.h.in.  Generated from configure.ac by autoheader.  */ + +/* Enable 24 bit per pixel in native framebuffer */ +#ifndef LIBVNCSERVER_ALLOW24BPP  +#define LIBVNCSERVER_ALLOW24BPP  1  +#endif + +/* work around when write() returns ENOENT but does not mean it */ +/* #undef LIBVNCSERVER_ENOENT_WORKAROUND */ + +/* Use ffmpeg (for vnc2mpg) */ +/* #undef LIBVNCSERVER_FFMPEG */ + +/* Define to 1 if you have the <arpa/inet.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_ARPA_INET_H  +#define LIBVNCSERVER_HAVE_ARPA_INET_H  1  +#endif + +/* Avahi/mDNS client build environment present */ +#ifndef LIBVNCSERVER_HAVE_AVAHI  +#define LIBVNCSERVER_HAVE_AVAHI  1  +#endif + +/* Define to 1 if you have the `crypt' function. */ +#ifndef LIBVNCSERVER_HAVE_CRYPT  +#define LIBVNCSERVER_HAVE_CRYPT  1  +#endif + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +/* #undef LIBVNCSERVER_HAVE_DOPRNT */ + +/* DPMS extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_DPMS */ + +/* FBPM extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_FBPM */ + +/* Define to 1 if you have the <fcntl.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_FCNTL_H  +#define LIBVNCSERVER_HAVE_FCNTL_H  1  +#endif + +/* Define to 1 if you have the `fork' function. */ +#ifndef LIBVNCSERVER_HAVE_FORK  +#define LIBVNCSERVER_HAVE_FORK  1  +#endif + +/* Define to 1 if you have the `ftime' function. */ +#ifndef LIBVNCSERVER_HAVE_FTIME  +#define LIBVNCSERVER_HAVE_FTIME  1  +#endif + +/* Define to 1 if you have the `geteuid' function. */ +#ifndef LIBVNCSERVER_HAVE_GETEUID  +#define LIBVNCSERVER_HAVE_GETEUID  1  +#endif + +/* Define to 1 if you have the `gethostbyname' function. */ +#ifndef LIBVNCSERVER_HAVE_GETHOSTBYNAME  +#define LIBVNCSERVER_HAVE_GETHOSTBYNAME  1  +#endif + +/* Define to 1 if you have the `gethostname' function. */ +#ifndef LIBVNCSERVER_HAVE_GETHOSTNAME  +#define LIBVNCSERVER_HAVE_GETHOSTNAME  1  +#endif + +/* Define to 1 if you have the `getpwnam' function. */ +#ifndef LIBVNCSERVER_HAVE_GETPWNAM  +#define LIBVNCSERVER_HAVE_GETPWNAM  1  +#endif + +/* Define to 1 if you have the `getpwuid' function. */ +#ifndef LIBVNCSERVER_HAVE_GETPWUID  +#define LIBVNCSERVER_HAVE_GETPWUID  1  +#endif + +/* Define to 1 if you have the `getspnam' function. */ +/* #undef LIBVNCSERVER_HAVE_GETSPNAM */ + +/* Define to 1 if you have the `gettimeofday' function. */ +#ifndef LIBVNCSERVER_HAVE_GETTIMEOFDAY  +#define LIBVNCSERVER_HAVE_GETTIMEOFDAY  1  +#endif + +/* Define to 1 if you have the `getuid' function. */ +#ifndef LIBVNCSERVER_HAVE_GETUID  +#define LIBVNCSERVER_HAVE_GETUID  1  +#endif + +/* Define to 1 if you have the `grantpt' function. */ +#ifndef LIBVNCSERVER_HAVE_GRANTPT  +#define LIBVNCSERVER_HAVE_GRANTPT  1  +#endif + +/* Define to 1 if you have the `inet_ntoa' function. */ +#ifndef LIBVNCSERVER_HAVE_INET_NTOA  +#define LIBVNCSERVER_HAVE_INET_NTOA  1  +#endif + +/* Define to 1 if you have the `initgroups' function. */ +#ifndef LIBVNCSERVER_HAVE_INITGROUPS  +#define LIBVNCSERVER_HAVE_INITGROUPS  1  +#endif + +/* Define to 1 if you have the <inttypes.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_INTTYPES_H  +#define LIBVNCSERVER_HAVE_INTTYPES_H  1  +#endif + +/* IRIX XReadDisplay available */ +/* #undef LIBVNCSERVER_HAVE_IRIX_XREADDISPLAY */ + +/* libcrypt library present */ +/* #undef LIBVNCSERVER_HAVE_LIBCRYPT */ + +/* openssl libcrypto library present */ +#ifndef LIBVNCSERVER_HAVE_LIBCRYPTO  +#define LIBVNCSERVER_HAVE_LIBCRYPTO  1  +#endif + +/* Define to 1 if you have the `cygipc' library (-lcygipc). */ +/* #undef LIBVNCSERVER_HAVE_LIBCYGIPC */ + +/* Define to 1 if you have the `jpeg' library (-ljpeg). */ +/* #undef LIBVNCSERVER_HAVE_LIBJPEG */ + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +/* #undef LIBVNCSERVER_HAVE_LIBNSL */ + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#ifndef LIBVNCSERVER_HAVE_LIBPTHREAD  +#define LIBVNCSERVER_HAVE_LIBPTHREAD  1  +#endif + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef LIBVNCSERVER_HAVE_LIBSOCKET */ + +/* openssl libssl library present */ +#ifndef LIBVNCSERVER_HAVE_LIBSSL  +#define LIBVNCSERVER_HAVE_LIBSSL  1  +#endif + +/* XDAMAGE extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_LIBXDAMAGE */ + +/* XFIXES extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_LIBXFIXES */ + +/* XINERAMA extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_LIBXINERAMA */ + +/* XRANDR extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_LIBXRANDR */ + +/* DEC-XTRAP extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_LIBXTRAP */ + +/* Define to 1 if you have the `z' library (-lz). */ +#ifndef LIBVNCSERVER_HAVE_LIBZ  +#define LIBVNCSERVER_HAVE_LIBZ  1  +#endif + +/* linux fb device build environment present */ +/* #undef LIBVNCSERVER_HAVE_LINUX_FB_H */ + +/* linux/input.h present */ +/* #undef LIBVNCSERVER_HAVE_LINUX_INPUT_H */ + +/* linux uinput device build environment present */ +/* #undef LIBVNCSERVER_HAVE_LINUX_UINPUT_H */ + +/* video4linux build environment present */ +/* #undef LIBVNCSERVER_HAVE_LINUX_VIDEODEV_H */ + +/* build MacOS X native display support */ +#ifndef LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY  +#define LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY  1  +#endif + +/* Define to 1 if you have the `memmove' function. */ +#ifndef LIBVNCSERVER_HAVE_MEMMOVE  +#define LIBVNCSERVER_HAVE_MEMMOVE  1  +#endif + +/* Define to 1 if you have the <memory.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_MEMORY_H  +#define LIBVNCSERVER_HAVE_MEMORY_H  1  +#endif + +/* Define to 1 if you have the `memset' function. */ +#ifndef LIBVNCSERVER_HAVE_MEMSET  +#define LIBVNCSERVER_HAVE_MEMSET  1  +#endif + +/* Define to 1 if you have the `mkfifo' function. */ +#ifndef LIBVNCSERVER_HAVE_MKFIFO  +#define LIBVNCSERVER_HAVE_MKFIFO  1  +#endif + +/* Define to 1 if you have the `mmap' function. */ +#ifndef LIBVNCSERVER_HAVE_MMAP  +#define LIBVNCSERVER_HAVE_MMAP  1  +#endif + +/* Define to 1 if you have the <netdb.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_NETDB_H  +#define LIBVNCSERVER_HAVE_NETDB_H  1  +#endif + +/* Define to 1 if you have the <netinet/in.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_NETINET_IN_H  +#define LIBVNCSERVER_HAVE_NETINET_IN_H  1  +#endif + +/* Define to 1 if you have the <pwd.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_PWD_H  +#define LIBVNCSERVER_HAVE_PWD_H  1  +#endif + +/* RECORD extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_RECORD */ + +/* Define to 1 if you have the `select' function. */ +#ifndef LIBVNCSERVER_HAVE_SELECT  +#define LIBVNCSERVER_HAVE_SELECT  1  +#endif + +/* Define to 1 if you have the `setegid' function. */ +#ifndef LIBVNCSERVER_HAVE_SETEGID  +#define LIBVNCSERVER_HAVE_SETEGID  1  +#endif + +/* Define to 1 if you have the `seteuid' function. */ +#ifndef LIBVNCSERVER_HAVE_SETEUID  +#define LIBVNCSERVER_HAVE_SETEUID  1  +#endif + +/* Define to 1 if you have the `setgid' function. */ +#ifndef LIBVNCSERVER_HAVE_SETGID  +#define LIBVNCSERVER_HAVE_SETGID  1  +#endif + +/* Define to 1 if you have the `setpgrp' function. */ +#ifndef LIBVNCSERVER_HAVE_SETPGRP  +#define LIBVNCSERVER_HAVE_SETPGRP  1  +#endif + +/* Define to 1 if you have the `setsid' function. */ +#ifndef LIBVNCSERVER_HAVE_SETSID  +#define LIBVNCSERVER_HAVE_SETSID  1  +#endif + +/* Define to 1 if you have the `setuid' function. */ +#ifndef LIBVNCSERVER_HAVE_SETUID  +#define LIBVNCSERVER_HAVE_SETUID  1  +#endif + +/* Define to 1 if you have the `setutxent' function. */ +#ifndef LIBVNCSERVER_HAVE_SETUTXENT  +#define LIBVNCSERVER_HAVE_SETUTXENT  1  +#endif + +/* Define to 1 if you have the `shmat' function. */ +#ifndef LIBVNCSERVER_HAVE_SHMAT  +#define LIBVNCSERVER_HAVE_SHMAT  1  +#endif + +/* Define to 1 if you have the `socket' function. */ +#ifndef LIBVNCSERVER_HAVE_SOCKET  +#define LIBVNCSERVER_HAVE_SOCKET  1  +#endif + +/* Solaris XReadScreen available */ +/* #undef LIBVNCSERVER_HAVE_SOLARIS_XREADSCREEN */ + +/* Define to 1 if `stat' has the bug that it succeeds when given the +   zero-length file name argument. */ +/* #undef LIBVNCSERVER_HAVE_STAT_EMPTY_STRING_BUG */ + +/* Define to 1 if you have the <stdint.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_STDINT_H  +#define LIBVNCSERVER_HAVE_STDINT_H  1  +#endif + +/* Define to 1 if you have the <stdlib.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_STDLIB_H  +#define LIBVNCSERVER_HAVE_STDLIB_H  1  +#endif + +/* Define to 1 if you have the `strchr' function. */ +#ifndef LIBVNCSERVER_HAVE_STRCHR  +#define LIBVNCSERVER_HAVE_STRCHR  1  +#endif + +/* Define to 1 if you have the `strcspn' function. */ +#ifndef LIBVNCSERVER_HAVE_STRCSPN  +#define LIBVNCSERVER_HAVE_STRCSPN  1  +#endif + +/* Define to 1 if you have the `strdup' function. */ +#ifndef LIBVNCSERVER_HAVE_STRDUP  +#define LIBVNCSERVER_HAVE_STRDUP  1  +#endif + +/* Define to 1 if you have the `strerror' function. */ +#ifndef LIBVNCSERVER_HAVE_STRERROR  +#define LIBVNCSERVER_HAVE_STRERROR  1  +#endif + +/* Define to 1 if you have the `strftime' function. */ +#ifndef LIBVNCSERVER_HAVE_STRFTIME  +#define LIBVNCSERVER_HAVE_STRFTIME  1  +#endif + +/* Define to 1 if you have the <strings.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_STRINGS_H  +#define LIBVNCSERVER_HAVE_STRINGS_H  1  +#endif + +/* Define to 1 if you have the <string.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_STRING_H  +#define LIBVNCSERVER_HAVE_STRING_H  1  +#endif + +/* Define to 1 if you have the `strstr' function. */ +#ifndef LIBVNCSERVER_HAVE_STRSTR  +#define LIBVNCSERVER_HAVE_STRSTR  1  +#endif + +/* Define to 1 if you have the <syslog.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_SYSLOG_H  +#define LIBVNCSERVER_HAVE_SYSLOG_H  1  +#endif + +/* Use the system libvncserver build environment for x11vnc. */ +/* #undef LIBVNCSERVER_HAVE_SYSTEM_LIBVNCSERVER */ + +/* Define to 1 if you have the <sys/ioctl.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_SYS_IOCTL_H  +#define LIBVNCSERVER_HAVE_SYS_IOCTL_H  1  +#endif + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_SYS_SOCKET_H  +#define LIBVNCSERVER_HAVE_SYS_SOCKET_H  1  +#endif + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_SYS_STAT_H  +#define LIBVNCSERVER_HAVE_SYS_STAT_H  1  +#endif + +/* Define to 1 if you have the <sys/stropts.h> header file. */ +/* #undef LIBVNCSERVER_HAVE_SYS_STROPTS_H */ + +/* Define to 1 if you have the <sys/timeb.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_SYS_TIMEB_H  +#define LIBVNCSERVER_HAVE_SYS_TIMEB_H  1  +#endif + +/* Define to 1 if you have the <sys/time.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_SYS_TIME_H  +#define LIBVNCSERVER_HAVE_SYS_TIME_H  1  +#endif + +/* Define to 1 if you have the <sys/types.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_SYS_TYPES_H  +#define LIBVNCSERVER_HAVE_SYS_TYPES_H  1  +#endif + +/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */ +#ifndef LIBVNCSERVER_HAVE_SYS_WAIT_H  +#define LIBVNCSERVER_HAVE_SYS_WAIT_H  1  +#endif + +/* Define to 1 if you have the <termios.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_TERMIOS_H  +#define LIBVNCSERVER_HAVE_TERMIOS_H  1  +#endif + +/* Define to 1 if compiler supports __thread */ +/* #undef LIBVNCSERVER_HAVE_TLS */ + +/* Define to 1 if you have the <unistd.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_UNISTD_H  +#define LIBVNCSERVER_HAVE_UNISTD_H  1  +#endif + +/* Define to 1 if you have the <utmpx.h> header file. */ +#ifndef LIBVNCSERVER_HAVE_UTMPX_H  +#define LIBVNCSERVER_HAVE_UTMPX_H  1  +#endif + +/* Define to 1 if you have the `vfork' function. */ +#ifndef LIBVNCSERVER_HAVE_VFORK  +#define LIBVNCSERVER_HAVE_VFORK  1  +#endif + +/* Define to 1 if you have the <vfork.h> header file. */ +/* #undef LIBVNCSERVER_HAVE_VFORK_H */ + +/* Define to 1 if you have the `vprintf' function. */ +#ifndef LIBVNCSERVER_HAVE_VPRINTF  +#define LIBVNCSERVER_HAVE_VPRINTF  1  +#endif + +/* Define to 1 if you have the `waitpid' function. */ +#ifndef LIBVNCSERVER_HAVE_WAITPID  +#define LIBVNCSERVER_HAVE_WAITPID  1  +#endif + +/* Define to 1 if `fork' works. */ +#ifndef LIBVNCSERVER_HAVE_WORKING_FORK  +#define LIBVNCSERVER_HAVE_WORKING_FORK  1  +#endif + +/* Define to 1 if `vfork' works. */ +#ifndef LIBVNCSERVER_HAVE_WORKING_VFORK  +#define LIBVNCSERVER_HAVE_WORKING_VFORK  1  +#endif + +/* X11 build environment present */ +/* #undef LIBVNCSERVER_HAVE_X11 */ + +/* open ssl X509_print_ex_fp available */ +#ifndef LIBVNCSERVER_HAVE_X509_PRINT_EX_FP  +#define LIBVNCSERVER_HAVE_X509_PRINT_EX_FP  1  +#endif + +/* XKEYBOARD extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_XKEYBOARD */ + +/* MIT-SHM extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_XSHM */ + +/* XTEST extension build environment present */ +/* #undef LIBVNCSERVER_HAVE_XTEST */ + +/* XTEST extension has XTestGrabControl */ +/* #undef LIBVNCSERVER_HAVE_XTESTGRABCONTROL */ + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing +   slash. */ +/* #undef LIBVNCSERVER_LSTAT_FOLLOWS_SLASHED_SYMLINK */ + +/* Need a typedef for in_addr_t */ +/* #undef LIBVNCSERVER_NEED_INADDR_T */ + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef LIBVNCSERVER_NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#ifndef LIBVNCSERVER_PACKAGE  +#define LIBVNCSERVER_PACKAGE  "x11vnc"  +#endif + +/* Define to the address where bug reports for this package should be sent. */ +#ifndef LIBVNCSERVER_PACKAGE_BUGREPORT  +#define LIBVNCSERVER_PACKAGE_BUGREPORT  "http://sourceforge.net/projects/libvncserver"  +#endif + +/* Define to the full name of this package. */ +#ifndef LIBVNCSERVER_PACKAGE_NAME  +#define LIBVNCSERVER_PACKAGE_NAME  "x11vnc"  +#endif + +/* Define to the full name and version of this package. */ +#ifndef LIBVNCSERVER_PACKAGE_STRING  +#define LIBVNCSERVER_PACKAGE_STRING  "x11vnc 0.9.12"  +#endif + +/* Define to the one symbol short name of this package. */ +#ifndef LIBVNCSERVER_PACKAGE_TARNAME  +#define LIBVNCSERVER_PACKAGE_TARNAME  "x11vnc"  +#endif + +/* Define to the version of this package. */ +#ifndef LIBVNCSERVER_PACKAGE_VERSION  +#define LIBVNCSERVER_PACKAGE_VERSION  "0.9.12"  +#endif + +/* The number of bytes in type char */ +/* #undef LIBVNCSERVER_SIZEOF_CHAR */ + +/* The number of bytes in type int */ +/* #undef LIBVNCSERVER_SIZEOF_INT */ + +/* The number of bytes in type long */ +/* #undef LIBVNCSERVER_SIZEOF_LONG */ + +/* The number of bytes in type short */ +/* #undef LIBVNCSERVER_SIZEOF_SHORT */ + +/* The number of bytes in type void* */ +/* #undef LIBVNCSERVER_SIZEOF_VOIDP */ + +/* Define to 1 if you have the ANSI C header files. */ +#ifndef LIBVNCSERVER_STDC_HEADERS  +#define LIBVNCSERVER_STDC_HEADERS  1  +#endif + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#ifndef LIBVNCSERVER_TIME_WITH_SYS_TIME  +#define LIBVNCSERVER_TIME_WITH_SYS_TIME  1  +#endif + +/* Version number of package */ +#ifndef LIBVNCSERVER_VERSION  +#define LIBVNCSERVER_VERSION  "0.9.12"  +#endif + +/* Enable support for gnutls in libvncclient */ +/* #undef LIBVNCSERVER_WITH_CLIENT_TLS */ + +/* Disable TightVNCFileTransfer protocol */ +#ifndef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER  +#define LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER  1  +#endif + +/* Define to 1 if your processor stores words with the most significant byte +   first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef LIBVNCSERVER_WORDS_BIGENDIAN */ + +/* Define to 1 if the X Window System is missing or not being used. */ +#ifndef LIBVNCSERVER_X_DISPLAY_MISSING  +#define LIBVNCSERVER_X_DISPLAY_MISSING  1  +#endif + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler +   calls it, or to nothing if 'inline' is not supported under any name.  */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `int' if <sys/types.h> does not define. */ +/* #undef pid_t */ + +/* Define to `unsigned' if <sys/types.h> does not define. */ +/* #undef size_t */ + +/* The type for socklen */ +/* #undef socklen_t */ + +/* Define as `fork' if `vfork' does not work. */ +/* #undef vfork */ +  +/* once: _RFB_RFBCONFIG_H */ +#endif diff --git a/3rdParty/LibVNC/src/rfb/rfbint.h b/3rdParty/LibVNC/src/rfb/rfbint.h new file mode 100644 index 0000000..f9816a0 --- /dev/null +++ b/3rdParty/LibVNC/src/rfb/rfbint.h @@ -0,0 +1,17 @@ +#ifndef _RFB_RFBINT_H +#define _RFB_RFBINT_H 1 +#ifndef _GENERATED_STDINT_H +#define _GENERATED_STDINT_H "x11vnc 0.9.12" +/* generated using a gnu compiler version i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664) Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ + +#include <stdint.h> + + +/* system headers have good uint64_t */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +#endif + +  /* once */ +#endif +#endif diff --git a/3rdParty/LibVNC/src/rfb/rfbproto.h b/3rdParty/LibVNC/src/rfb/rfbproto.h new file mode 100644 index 0000000..b6f201c --- /dev/null +++ b/3rdParty/LibVNC/src/rfb/rfbproto.h @@ -0,0 +1,1377 @@ +#ifndef RFBPROTO_H +#define RFBPROTO_H + +/* + *  Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin + *  Copyright (C) 2000-2002 Constantin Kaplinsky.  All Rights Reserved. + *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved. + *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved. + * + *  This is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This software is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this software; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, + *  USA. + */ + +/* + * rfbproto.h - header file for the RFB protocol version 3.3 + * + * Uses types CARD<n> for an n-bit unsigned integer, INT<n> for an n-bit signed + * integer (for n = 8, 16 and 32). + * + * All multiple byte integers are in big endian (network) order (most + * significant byte first).  Unless noted otherwise there is no special + * alignment of protocol structures. + * + * + * Once the initial handshaking is done, all messages start with a type byte, + * (usually) followed by message-specific data.  The order of definitions in + * this file is as follows: + * + *  (1) Structures used in several types of message. + *  (2) Structures used in the initial handshaking. + *  (3) Message types. + *  (4) Encoding types. + *  (5) For each message type, the form of the data following the type byte. + *      Sometimes this is defined by a single structure but the more complex + *      messages have to be explained by comments. + */ + + +#if defined(WIN32) && !defined(__MINGW32__) +#define LIBVNCSERVER_WORDS_BIGENDIAN +#define rfbBool int +#include <sys/timeb.h> +#include <winsock.h> +#undef SOCKET +#define SOCKET int +#else +#include <rfb/rfbconfig.h> +#include <rfb/rfbint.h> +#endif + +#ifdef LIBVNCSERVER_HAVE_LIBZ +#include <zlib.h> +#ifdef __CHECKER__ +#undef Z_NULL +#define Z_NULL NULL +#endif +#endif + + +#if !defined(WIN32) || defined(__MINGW32__) +#define max(a,b) (((a)>(b))?(a):(b)) +#ifdef LIBVNCSERVER_HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef LIBVNCSERVER_HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#define SOCKET int +typedef int8_t rfbBool; +#undef FALSE +#define FALSE 0 +#undef TRUE +#define TRUE -1 +#endif + +typedef uint32_t rfbKeySym; +typedef uint32_t rfbPixel; + +#ifdef LIBVNCSERVER_NEED_INADDR_T +typedef uint32_t in_addr_t; +#endif + +#ifndef INADDR_NONE +#define                INADDR_NONE     ((in_addr_t) 0xffffffff) +#endif + +#define MAX_ENCODINGS 20 + +/***************************************************************************** + * + * Structures used in several messages + * + *****************************************************************************/ + +/*----------------------------------------------------------------------------- + * Structure used to specify a rectangle.  This structure is a multiple of 4 + * bytes so that it can be interspersed with 32-bit pixel data without + * affecting alignment. + */ + +typedef struct { +    uint16_t x; +    uint16_t y; +    uint16_t w; +    uint16_t h; +} rfbRectangle; + +#define sz_rfbRectangle 8 + + +/*----------------------------------------------------------------------------- + * Structure used to specify pixel format. + */ + +typedef struct { + +    uint8_t bitsPerPixel;		/* 8,16,32 only */ + +    uint8_t depth;		/* 8 to 32 */ + +    uint8_t bigEndian;		/* True if multi-byte pixels are interpreted +				   as big endian, or if single-bit-per-pixel +				   has most significant bit of the byte +				   corresponding to first (leftmost) pixel. Of +				   course this is meaningless for 8 bits/pix */ + +    uint8_t trueColour;		/* If false then we need a "colour map" to +				   convert pixels to RGB.  If true, xxxMax and +				   xxxShift specify bits used for red, green +				   and blue */ + +    /* the following fields are only meaningful if trueColour is true */ + +    uint16_t redMax;		/* maximum red value (= 2^n - 1 where n is the +				   number of bits used for red). Note this +				   value is always in big endian order. */ + +    uint16_t greenMax;		/* similar for green */ + +    uint16_t blueMax;		/* and blue */ + +    uint8_t redShift;		/* number of shifts needed to get the red +				   value in a pixel to the least significant +				   bit. To find the red value from a given +				   pixel, do the following: +				   1) Swap pixel value according to bigEndian +				      (e.g. if bigEndian is false and host byte +				      order is big endian, then swap). +				   2) Shift right by redShift. +				   3) AND with redMax (in host byte order). +				   4) You now have the red value between 0 and +				      redMax. */ + +    uint8_t greenShift;		/* similar for green */ + +    uint8_t blueShift;		/* and blue */ + +    uint8_t pad1; +    uint16_t pad2; + +} rfbPixelFormat; + +#define sz_rfbPixelFormat 16 + +/* UltraVNC: Color settings values */ +#define rfbPFFullColors		0 +#define rfbPF256Colors		1 +#define rfbPF64Colors		2 +#define rfbPF8Colors		3 +#define rfbPF8GreyColors	4 +#define rfbPF4GreyColors	5 +#define rfbPF2GreyColors	6 + + +/***************************************************************************** + * + * Initial handshaking messages + * + *****************************************************************************/ + +/*----------------------------------------------------------------------------- + * Protocol Version + * + * The server always sends 12 bytes to start which identifies the latest RFB + * protocol version number which it supports.  These bytes are interpreted + * as a string of 12 ASCII characters in the format "RFB xxx.yyy\n" where + * xxx and yyy are the major and minor version numbers (for version 3.3 + * this is "RFB 003.003\n"). + * + * The client then replies with a similar 12-byte message giving the version + * number of the protocol which should actually be used (which may be different + * to that quoted by the server). + * + * It is intended that both clients and servers may provide some level of + * backwards compatibility by this mechanism.  Servers in particular should + * attempt to provide backwards compatibility, and even forwards compatibility + * to some extent.  For example if a client demands version 3.1 of the + * protocol, a 3.0 server can probably assume that by ignoring requests for + * encoding types it doesn't understand, everything will still work OK.  This + * will probably not be the case for changes in the major version number. + * + * The format string below can be used in sprintf or sscanf to generate or + * decode the version string respectively. + */ + +#define rfbProtocolVersionFormat "RFB %03d.%03d\n" +#define rfbProtocolMajorVersion 3 +#define rfbProtocolMinorVersion 8 +/* UltraVNC Viewer examines rfbProtocolMinorVersion number (4, and 6) + * to identify if the server supports File Transfer + */ + +typedef char rfbProtocolVersionMsg[13];	/* allow extra byte for null */ + +#define sz_rfbProtocolVersionMsg 12 + +/* + * Negotiation of the security type (protocol version 3.7) + * + * Once the protocol version has been decided, the server either sends a list + * of supported security types, or informs the client about an error (when the + * number of security types is 0).  Security type rfbSecTypeTight is used to + * enable TightVNC-specific protocol extensions.  The value rfbSecTypeVncAuth + * stands for classic VNC authentication. + * + * The client selects a particular security type from the list provided by the + * server. + */ + +#define rfbSecTypeInvalid 0 +#define rfbSecTypeNone 1 +#define rfbSecTypeVncAuth 2 + + +/*----------------------------------------------------------------------------- + * Authentication + * + * Once the protocol version has been decided, the server then sends a 32-bit + * word indicating whether any authentication is needed on the connection. + * The value of this word determines the authentication scheme in use.  For + * version 3.0 of the protocol this may have one of the following values: + */ + +#define rfbConnFailed 0 +#define rfbNoAuth 1 +#define rfbVncAuth 2 + +#define rfbRA2 5 +#define rfbRA2ne 6 +#define rfbSSPI 7 +#define rfbSSPIne 8 +#define rfbTight 16 +#define rfbUltra 17 +#define rfbTLS 18 +#define rfbVeNCrypt 19 +#define rfbMSLogon 0xfffffffa + +#define rfbVeNCryptPlain 256 +#define rfbVeNCryptTLSNone 257 +#define rfbVeNCryptTLSVNC 258 +#define rfbVeNCryptTLSPlain 259 +#define rfbVeNCryptX509None 260 +#define rfbVeNCryptX509VNC 261 +#define rfbVeNCryptX509Plain 262 +#define rfbVeNCryptX509SASL 263 +#define rfbVeNCryptTLSSASL 264 + +/* + * rfbConnFailed:	For some reason the connection failed (e.g. the server + *			cannot support the desired protocol version).  This is + *			followed by a string describing the reason (where a + *			string is specified as a 32-bit length followed by that + *			many ASCII characters). + * + * rfbNoAuth:		No authentication is needed. + * + * rfbVncAuth:		The VNC authentication scheme is to be used.  A 16-byte + *			challenge follows, which the client encrypts as + *			appropriate using the password and sends the resulting + *			16-byte response.  If the response is correct, the + *			server sends the 32-bit word rfbVncAuthOK.  If a simple + *			failure happens, the server sends rfbVncAuthFailed and + *			closes the connection. If the server decides that too + *			many failures have occurred, it sends rfbVncAuthTooMany + *			and closes the connection.  In the latter case, the + *			server should not allow an immediate reconnection by + *			the client. + */ + +#define rfbVncAuthOK 0 +#define rfbVncAuthFailed 1 +#define rfbVncAuthTooMany 2 + + +/*----------------------------------------------------------------------------- + * Client Initialisation Message + * + * Once the client and server are sure that they're happy to talk to one + * another, the client sends an initialisation message.  At present this + * message only consists of a boolean indicating whether the server should try + * to share the desktop by leaving other clients connected, or give exclusive + * access to this client by disconnecting all other clients. + */ + +typedef struct { +    uint8_t shared; +} rfbClientInitMsg; + +#define sz_rfbClientInitMsg 1 + + +/*----------------------------------------------------------------------------- + * Server Initialisation Message + * + * After the client initialisation message, the server sends one of its own. + * This tells the client the width and height of the server's framebuffer, + * its pixel format and the name associated with the desktop. + */ + +typedef struct { +    uint16_t framebufferWidth; +    uint16_t framebufferHeight; +    rfbPixelFormat format;	/* the server's preferred pixel format */ +    uint32_t nameLength; +    /* followed by char name[nameLength] */ +} rfbServerInitMsg; + +#define sz_rfbServerInitMsg (8 + sz_rfbPixelFormat) + + +/* + * Following the server initialisation message it's up to the client to send + * whichever protocol messages it wants.  Typically it will send a + * SetPixelFormat message and a SetEncodings message, followed by a + * FramebufferUpdateRequest.  From then on the server will send + * FramebufferUpdate messages in response to the client's + * FramebufferUpdateRequest messages.  The client should send + * FramebufferUpdateRequest messages with incremental set to true when it has + * finished processing one FramebufferUpdate and is ready to process another. + * With a fast client, the rate at which FramebufferUpdateRequests are sent + * should be regulated to avoid hogging the network. + */ + + + +/***************************************************************************** + * + * Message types + * + *****************************************************************************/ + +/* server -> client */ + +#define rfbFramebufferUpdate 0 +#define rfbSetColourMapEntries 1 +#define rfbBell 2 +#define rfbServerCutText 3 +/* Modif sf@2002 */ +#define rfbResizeFrameBuffer 4 +#define rfbKeyFrameUpdate 5 +#define rfbPalmVNCReSizeFrameBuffer 0xF + +/* client -> server */ + +#define rfbSetPixelFormat 0 +#define rfbFixColourMapEntries 1	/* not currently supported */ +#define rfbSetEncodings 2 +#define rfbFramebufferUpdateRequest 3 +#define rfbKeyEvent 4 +#define rfbPointerEvent 5 +#define rfbClientCutText 6 +/* Modif sf@2002 - actually bidirectionnal */ +#define rfbFileTransfer 7 +/* Modif sf@2002 */ +#define rfbSetScale 8 +/* Modif rdv@2002 */ +#define rfbSetServerInput	9 +/* Modif rdv@2002 */ +#define rfbSetSW	10 +/* Modif sf@2002 - TextChat - Bidirectionnal */ +#define rfbTextChat	11 +/* Modif cs@2005 */ +#define rfbKeyFrameRequest 12 +/* PalmVNC 1.4 & 2.0 SetScale Factor message */ +#define rfbPalmVNCSetScaleFactor 0xF + + + + +/***************************************************************************** + * + * Encoding types + * + *****************************************************************************/ + +#define rfbEncodingRaw 0 +#define rfbEncodingCopyRect 1 +#define rfbEncodingRRE 2 +#define rfbEncodingCoRRE 4 +#define rfbEncodingHextile 5 +#define rfbEncodingZlib 6 +#define rfbEncodingTight 7 +#define rfbEncodingZlibHex 8 +#define rfbEncodingUltra 9 +#define rfbEncodingZRLE 16 +#define rfbEncodingZYWRLE 17 + +/* Cache & XOR-Zlib - rdv@2002 */ +#define rfbEncodingCache                 0xFFFF0000 +#define rfbEncodingCacheEnable           0xFFFF0001 +#define rfbEncodingXOR_Zlib              0xFFFF0002 +#define rfbEncodingXORMonoColor_Zlib     0xFFFF0003 +#define rfbEncodingXORMultiColor_Zlib    0xFFFF0004 +#define rfbEncodingSolidColor            0xFFFF0005 +#define rfbEncodingXOREnable             0xFFFF0006 +#define rfbEncodingCacheZip              0xFFFF0007 +#define rfbEncodingSolMonoZip            0xFFFF0008 +#define rfbEncodingUltraZip              0xFFFF0009 + +/* + * Special encoding numbers: + *   0xFFFFFF00 .. 0xFFFFFF0F -- encoding-specific compression levels; + *   0xFFFFFF10 .. 0xFFFFFF1F -- mouse cursor shape data; + *   0xFFFFFF20 .. 0xFFFFFF2F -- various protocol extensions; + *   0xFFFFFF30 .. 0xFFFFFFDF -- not allocated yet; + *   0xFFFFFFE0 .. 0xFFFFFFEF -- quality level for JPEG compressor; + *   0xFFFFFFF0 .. 0xFFFFFFFF -- cross-encoding compression levels. + */ + +#define rfbEncodingCompressLevel0  0xFFFFFF00 +#define rfbEncodingCompressLevel1  0xFFFFFF01 +#define rfbEncodingCompressLevel2  0xFFFFFF02 +#define rfbEncodingCompressLevel3  0xFFFFFF03 +#define rfbEncodingCompressLevel4  0xFFFFFF04 +#define rfbEncodingCompressLevel5  0xFFFFFF05 +#define rfbEncodingCompressLevel6  0xFFFFFF06 +#define rfbEncodingCompressLevel7  0xFFFFFF07 +#define rfbEncodingCompressLevel8  0xFFFFFF08 +#define rfbEncodingCompressLevel9  0xFFFFFF09 + +#define rfbEncodingXCursor         0xFFFFFF10 +#define rfbEncodingRichCursor      0xFFFFFF11 +#define rfbEncodingPointerPos      0xFFFFFF18 + +#define rfbEncodingLastRect           0xFFFFFF20 +#define rfbEncodingNewFBSize          0xFFFFFF21 + +#define rfbEncodingQualityLevel0   0xFFFFFFE0 +#define rfbEncodingQualityLevel1   0xFFFFFFE1 +#define rfbEncodingQualityLevel2   0xFFFFFFE2 +#define rfbEncodingQualityLevel3   0xFFFFFFE3 +#define rfbEncodingQualityLevel4   0xFFFFFFE4 +#define rfbEncodingQualityLevel5   0xFFFFFFE5 +#define rfbEncodingQualityLevel6   0xFFFFFFE6 +#define rfbEncodingQualityLevel7   0xFFFFFFE7 +#define rfbEncodingQualityLevel8   0xFFFFFFE8 +#define rfbEncodingQualityLevel9   0xFFFFFFE9 + + +/* LibVNCServer additions.   We claim 0xFFFE0000 - 0xFFFE00FF */ +#define rfbEncodingKeyboardLedState   0xFFFE0000 +#define rfbEncodingSupportedMessages  0xFFFE0001 +#define rfbEncodingSupportedEncodings 0xFFFE0002 +#define rfbEncodingServerIdentity     0xFFFE0003 + + +/***************************************************************************** + * + * Server -> client message definitions + * + *****************************************************************************/ + + +/*----------------------------------------------------------------------------- + * FramebufferUpdate - a block of rectangles to be copied to the framebuffer. + * + * This message consists of a header giving the number of rectangles of pixel + * data followed by the rectangles themselves.  The header is padded so that + * together with the type byte it is an exact multiple of 4 bytes (to help + * with alignment of 32-bit pixels): + */ + +typedef struct { +    uint8_t type;			/* always rfbFramebufferUpdate */ +    uint8_t pad; +    uint16_t nRects; +    /* followed by nRects rectangles */ +} rfbFramebufferUpdateMsg; + +#define sz_rfbFramebufferUpdateMsg 4 + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * KeyFrameUpdate - Acknowledgment of a key frame request, it tells the client + * that the next update received will be a key frame. + */ + +typedef struct { +    uint8_t type; +} rfbKeyFrameUpdateMsg; + +#define sz_rfbKeyFrameUpdateMsg 1 + + +/* + * Each rectangle of pixel data consists of a header describing the position + * and size of the rectangle and a type word describing the encoding of the + * pixel data, followed finally by the pixel data.  Note that if the client has + * not sent a SetEncodings message then it will only receive raw pixel data. + * Also note again that this structure is a multiple of 4 bytes. + */ + +typedef struct { +    rfbRectangle r; +    uint32_t encoding;	/* one of the encoding types rfbEncoding... */ +} rfbFramebufferUpdateRectHeader; + +#define sz_rfbFramebufferUpdateRectHeader (sz_rfbRectangle + 4) + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Supported Messages Encoding.  This encoding does not contain any pixel data. + * Instead, it contains 2 sets of bitflags.  These bitflags indicate what messages + * are supported by the server. + * rect->w contains byte count + */ + +typedef struct { +  uint8_t client2server[32]; /* maximum of 256 message types (256/8)=32 */ +  uint8_t server2client[32]; /* maximum of 256 message types (256/8)=32 */ +} rfbSupportedMessages; + +#define sz_rfbSupportedMessages 64 + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Supported Encodings Encoding.  This encoding does not contain any pixel data. + * Instead, it contains a list of (uint32_t) Encodings supported by this server. + * rect->w contains byte count + * rect->h contains encoding count + */ + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Server Identity Encoding.  This encoding does not contain any pixel data. + * Instead, it contains a text string containing information about the server. + * ie: "x11vnc: 0.8.1 lastmod: 2006-04-25 (libvncserver 0.9pre)\0" + * rect->w contains byte count + */ + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Raw Encoding.  Pixels are sent in top-to-bottom scanline order, + * left-to-right within a scanline with no padding in between. + */ + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * KeyboardLedState Encoding.  The X coordinate contains the Locked Modifiers + * so that a remote troubleshooter can identify that the users 'Caps Lock'  + * is set...   (It helps a *lot* when the users are untrained) + */ +#define rfbKeyboardMaskShift        1 +#define rfbKeyboardMaskCapsLock     2 +#define rfbKeyboardMaskControl      4 +#define rfbKeyboardMaskAlt          8 +#define rfbKeyboardMaskMeta        16 +#define rfbKeyboardMaskSuper       32 +#define rfbKeyboardMaskHyper       64 +#define rfbKeyboardMaskNumLock    128 +#define rfbKeyboardMaskScrollLock 256 +#define rfbKeyboardMaskAltGraph   512 + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * CopyRect Encoding.  The pixels are specified simply by the x and y position + * of the source rectangle. + */ + +typedef struct { +    uint16_t srcX; +    uint16_t srcY; +} rfbCopyRect; + +#define sz_rfbCopyRect 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * RRE - Rise-and-Run-length Encoding.  We have an rfbRREHeader structure + * giving the number of subrectangles following.  Finally the data follows in + * the form [<bgpixel><subrect><subrect>...] where each <subrect> is + * [<pixel><rfbRectangle>]. + */ + +typedef struct { +    uint32_t nSubrects; +} rfbRREHeader; + +#define sz_rfbRREHeader 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * CoRRE - Compact RRE Encoding.  We have an rfbRREHeader structure giving + * the number of subrectangles following.  Finally the data follows in the form + * [<bgpixel><subrect><subrect>...] where each <subrect> is + * [<pixel><rfbCoRRERectangle>].  This means that + * the whole rectangle must be at most 255x255 pixels. + */ + +typedef struct { +    uint8_t x; +    uint8_t y; +    uint8_t w; +    uint8_t h; +} rfbCoRRERectangle; + +#define sz_rfbCoRRERectangle 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Hextile Encoding.  The rectangle is divided up into "tiles" of 16x16 pixels, + * starting at the top left going in left-to-right, top-to-bottom order.  If + * the width of the rectangle is not an exact multiple of 16 then the width of + * the last tile in each row will be correspondingly smaller.  Similarly if the + * height is not an exact multiple of 16 then the height of each tile in the + * final row will also be smaller.  Each tile begins with a "subencoding" type + * byte, which is a mask made up of a number of bits.  If the Raw bit is set + * then the other bits are irrelevant; w*h pixel values follow (where w and h + * are the width and height of the tile).  Otherwise the tile is encoded in a + * similar way to RRE, except that the position and size of each subrectangle + * can be specified in just two bytes.  The other bits in the mask are as + * follows: + * + * BackgroundSpecified - if set, a pixel value follows which specifies + *    the background colour for this tile.  The first non-raw tile in a + *    rectangle must have this bit set.  If this bit isn't set then the + *    background is the same as the last tile. + * + * ForegroundSpecified - if set, a pixel value follows which specifies + *    the foreground colour to be used for all subrectangles in this tile. + *    If this bit is set then the SubrectsColoured bit must be zero. + * + * AnySubrects - if set, a single byte follows giving the number of + *    subrectangles following.  If not set, there are no subrectangles (i.e. + *    the whole tile is just solid background colour). + * + * SubrectsColoured - if set then each subrectangle is preceded by a pixel + *    value giving the colour of that subrectangle.  If not set, all + *    subrectangles are the same colour, the foreground colour;  if the + *    ForegroundSpecified bit wasn't set then the foreground is the same as + *    the last tile. + * + * The position and size of each subrectangle is specified in two bytes.  The + * Pack macros below can be used to generate the two bytes from x, y, w, h, + * and the Extract macros can be used to extract the x, y, w, h values from + * the two bytes. + */ + +#define rfbHextileRaw			(1 << 0) +#define rfbHextileBackgroundSpecified	(1 << 1) +#define rfbHextileForegroundSpecified	(1 << 2) +#define rfbHextileAnySubrects		(1 << 3) +#define rfbHextileSubrectsColoured	(1 << 4) + +#define rfbHextilePackXY(x,y) (((x) << 4) | (y)) +#define rfbHextilePackWH(w,h) ((((w)-1) << 4) | ((h)-1)) +#define rfbHextileExtractX(byte) ((byte) >> 4) +#define rfbHextileExtractY(byte) ((byte) & 0xf) +#define rfbHextileExtractW(byte) (((byte) >> 4) + 1) +#define rfbHextileExtractH(byte) (((byte) & 0xf) + 1) + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * zlib - zlib compressed Encoding.  We have an rfbZlibHeader structure + * giving the number of bytes following.  Finally the data follows is + * zlib compressed version of the raw pixel data as negotiated. + * (NOTE: also used by Ultra Encoding) + */ + +typedef struct { +    uint32_t nBytes; +} rfbZlibHeader; + +#define sz_rfbZlibHeader 4 + +#ifdef LIBVNCSERVER_HAVE_LIBZ + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Tight Encoding. + * + *-- The first byte of each Tight-encoded rectangle is a "compression control + *   byte". Its format is as follows (bit 0 is the least significant one): + * + *   bit 0:    if 1, then compression stream 0 should be reset; + *   bit 1:    if 1, then compression stream 1 should be reset; + *   bit 2:    if 1, then compression stream 2 should be reset; + *   bit 3:    if 1, then compression stream 3 should be reset; + *   bits 7-4: if 1000 (0x08), then the compression type is "fill", + *             if 1001 (0x09), then the compression type is "jpeg", + *             if 0xxx, then the compression type is "basic", + *             values greater than 1001 are not valid. + * + * If the compression type is "basic", then bits 6..4 of the + * compression control byte (those xxx in 0xxx) specify the following: + * + *   bits 5-4:  decimal representation is the index of a particular zlib + *              stream which should be used for decompressing the data; + *   bit 6:     if 1, then a "filter id" byte is following this byte. + * + *-- The data that follows after the compression control byte described + * above depends on the compression type ("fill", "jpeg" or "basic"). + * + *-- If the compression type is "fill", then the only pixel value follows, in + * client pixel format (see NOTE 1). This value applies to all pixels of the + * rectangle. + * + *-- If the compression type is "jpeg", the following data stream looks like + * this: + * + *   1..3 bytes:  data size (N) in compact representation; + *   N bytes:     JPEG image. + * + * Data size is compactly represented in one, two or three bytes, according + * to the following scheme: + * + *  0xxxxxxx                    (for values 0..127) + *  1xxxxxxx 0yyyyyyy           (for values 128..16383) + *  1xxxxxxx 1yyyyyyy zzzzzzzz  (for values 16384..4194303) + * + * Here each character denotes one bit, xxxxxxx are the least significant 7 + * bits of the value (bits 0-6), yyyyyyy are bits 7-13, and zzzzzzzz are the + * most significant 8 bits (bits 14-21). For example, decimal value 10000 + * should be represented as two bytes: binary 10010000 01001110, or + * hexadecimal 90 4E. + * + *-- If the compression type is "basic" and bit 6 of the compression control + * byte was set to 1, then the next (second) byte specifies "filter id" which + * tells the decoder what filter type was used by the encoder to pre-process + * pixel data before the compression. The "filter id" byte can be one of the + * following: + * + *   0:  no filter ("copy" filter); + *   1:  "palette" filter; + *   2:  "gradient" filter. + * + *-- If bit 6 of the compression control byte is set to 0 (no "filter id" + * byte), or if the filter id is 0, then raw pixel values in the client + * format (see NOTE 1) will be compressed. See below details on the + * compression. + * + *-- The "gradient" filter pre-processes pixel data with a simple algorithm + * which converts each color component to a difference between a "predicted" + * intensity and the actual intensity. Such a technique does not affect + * uncompressed data size, but helps to compress photo-like images better.  + * Pseudo-code for converting intensities to differences is the following: + * + *   P[i,j] := V[i-1,j] + V[i,j-1] - V[i-1,j-1]; + *   if (P[i,j] < 0) then P[i,j] := 0; + *   if (P[i,j] > MAX) then P[i,j] := MAX; + *   D[i,j] := V[i,j] - P[i,j]; + * + * Here V[i,j] is the intensity of a color component for a pixel at + * coordinates (i,j). MAX is the maximum value of intensity for a color + * component. + * + *-- The "palette" filter converts true-color pixel data to indexed colors + * and a palette which can consist of 2..256 colors. If the number of colors + * is 2, then each pixel is encoded in 1 bit, otherwise 8 bits is used to + * encode one pixel. 1-bit encoding is performed such way that the most + * significant bits correspond to the leftmost pixels, and each raw of pixels + * is aligned to the byte boundary. When "palette" filter is used, the + * palette is sent before the pixel data. The palette begins with an unsigned + * byte which value is the number of colors in the palette minus 1 (i.e. 1 + * means 2 colors, 255 means 256 colors in the palette). Then follows the + * palette itself which consist of pixel values in client pixel format (see + * NOTE 1). + * + *-- The pixel data is compressed using the zlib library. But if the data + * size after applying the filter but before the compression is less then 12, + * then the data is sent as is, uncompressed. Four separate zlib streams + * (0..3) can be used and the decoder should read the actual stream id from + * the compression control byte (see NOTE 2). + * + * If the compression is not used, then the pixel data is sent as is, + * otherwise the data stream looks like this: + * + *   1..3 bytes:  data size (N) in compact representation; + *   N bytes:     zlib-compressed data. + * + * Data size is compactly represented in one, two or three bytes, just like + * in the "jpeg" compression method (see above). + * + *-- NOTE 1. If the color depth is 24, and all three color components are + * 8-bit wide, then one pixel in Tight encoding is always represented by + * three bytes, where the first byte is red component, the second byte is + * green component, and the third byte is blue component of the pixel color + * value. This applies to colors in palettes as well. + * + *-- NOTE 2. The decoder must reset compression streams' states before + * decoding the rectangle, if some of bits 0,1,2,3 in the compression control + * byte are set to 1. Note that the decoder must reset zlib streams even if + * the compression type is "fill" or "jpeg". + * + *-- NOTE 3. The "gradient" filter and "jpeg" compression may be used only + * when bits-per-pixel value is either 16 or 32, not 8. + * + *-- NOTE 4. The width of any Tight-encoded rectangle cannot exceed 2048 + * pixels. If a rectangle is wider, it must be split into several rectangles + * and each one should be encoded separately. + * + */ + +#define rfbTightExplicitFilter         0x04 +#define rfbTightFill                   0x08 +#define rfbTightJpeg                   0x09 +#define rfbTightMaxSubencoding         0x09 + +/* Filters to improve compression efficiency */ +#define rfbTightFilterCopy             0x00 +#define rfbTightFilterPalette          0x01 +#define rfbTightFilterGradient         0x02 + +#endif + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * XCursor encoding. This is a special encoding used to transmit X-style + * cursor shapes from server to clients. Note that for this encoding, + * coordinates in rfbFramebufferUpdateRectHeader structure hold hotspot + * position (r.x, r.y) and cursor size (r.w, r.h). If (w * h != 0), two RGB + * samples are sent after header in the rfbXCursorColors structure. They + * denote foreground and background colors of the cursor. If a client + * supports only black-and-white cursors, it should ignore these colors and + * assume that foreground is black and background is white. Next, two bitmaps + * (1 bits per pixel) follow: first one with actual data (value 0 denotes + * background color, value 1 denotes foreground color), second one with + * transparency data (bits with zero value mean that these pixels are + * transparent). Both bitmaps represent cursor data in a byte stream, from + * left to right, from top to bottom, and each row is byte-aligned. Most + * significant bits correspond to leftmost pixels. The number of bytes in + * each row can be calculated as ((w + 7) / 8). If (w * h == 0), cursor + * should be hidden (or default local cursor should be set by the client). + */ + +typedef struct { +    uint8_t foreRed; +    uint8_t foreGreen; +    uint8_t foreBlue; +    uint8_t backRed; +    uint8_t backGreen; +    uint8_t backBlue; +} rfbXCursorColors; + +#define sz_rfbXCursorColors 6 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * RichCursor encoding. This is a special encoding used to transmit cursor + * shapes from server to clients. It is similar to the XCursor encoding but + * uses client pixel format instead of two RGB colors to represent cursor + * image. For this encoding, coordinates in rfbFramebufferUpdateRectHeader + * structure hold hotspot position (r.x, r.y) and cursor size (r.w, r.h). + * After header, two pixmaps follow: first one with cursor image in current + * client pixel format (like in raw encoding), second with transparency data + * (1 bit per pixel, exactly the same format as used for transparency bitmap + * in the XCursor encoding). If (w * h == 0), cursor should be hidden (or + * default local cursor should be set by the client). + */ + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * ZRLE - encoding combining Zlib compression, tiling, palettisation and + * run-length encoding. + */ + +typedef struct { +    uint32_t length; +} rfbZRLEHeader; + +#define sz_rfbZRLEHeader 4 + +#define rfbZRLETileWidth 64 +#define rfbZRLETileHeight 64 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * ZLIBHEX - zlib compressed Hextile Encoding.  Essentially, this is the + * hextile encoding with zlib compression on the tiles that can not be + * efficiently encoded with one of the other hextile subencodings.  The + * new zlib subencoding uses two bytes to specify the length of the + * compressed tile and then the compressed data follows.  As with the + * raw sub-encoding, the zlib subencoding invalidates the other + * values, if they are also set. + */ + +#define rfbHextileZlibRaw		(1 << 5) +#define rfbHextileZlibHex		(1 << 6) +#define rfbHextileZlibMono		(1 << 7) + + +/*----------------------------------------------------------------------------- + * SetColourMapEntries - these messages are only sent if the pixel + * format uses a "colour map" (i.e. trueColour false) and the client has not + * fixed the entire colour map using FixColourMapEntries.  In addition they + * will only start being sent after the client has sent its first + * FramebufferUpdateRequest.  So if the client always tells the server to use + * trueColour then it never needs to process this type of message. + */ + +typedef struct { +    uint8_t type;			/* always rfbSetColourMapEntries */ +    uint8_t pad; +    uint16_t firstColour; +    uint16_t nColours; + +    /* Followed by nColours * 3 * uint16_t +       r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */ + +} rfbSetColourMapEntriesMsg; + +#define sz_rfbSetColourMapEntriesMsg 6 + + + +/*----------------------------------------------------------------------------- + * Bell - ring a bell on the client if it has one. + */ + +typedef struct { +    uint8_t type;			/* always rfbBell */ +} rfbBellMsg; + +#define sz_rfbBellMsg 1 + + + +/*----------------------------------------------------------------------------- + * ServerCutText - the server has new text in its cut buffer. + */ + +typedef struct { +    uint8_t type;			/* always rfbServerCutText */ +    uint8_t pad1; +    uint16_t pad2; +    uint32_t length; +    /* followed by char text[length] */ +} rfbServerCutTextMsg; + +#define sz_rfbServerCutTextMsg 8 + + +/*----------------------------------------------------------------------------- + * //  Modif sf@2002 + * FileTransferMsg - The client sends FileTransfer message. + * Bidirectional message - Files can be sent from client to server & vice versa + */ + +typedef struct _rfbFileTransferMsg { +    uint8_t type;			/* always rfbFileTransfer */ +    uint8_t contentType;  /*  See defines below */ +    uint8_t contentParam;/*  Other possible content classification (Dir or File name, etc..) */ +    uint8_t pad;         /* It appears that UltraVNC *forgot* to Swap16IfLE(contentParam) */ +    uint32_t size;		/*  FileSize or packet index or error or other  */ +/*  uint32_t sizeH;		 Additional 32Bits params to handle big values. Only for V2 (we want backward compatibility between all V1 versions) */ +    uint32_t length; +    /* followed by data char text[length] */ +} rfbFileTransferMsg; + +#define sz_rfbFileTransferMsg	12 + +#define rfbFileTransferVersion  2 /*  v1 is the old FT version ( <= 1.0.0 RC18 versions) */ + +/*  FileTransfer Content types and Params defines */ +#define rfbDirContentRequest	1 /*  Client asks for the content of a given Server directory */ +#define rfbDirPacket			2 /*  Full directory name or full file name. */ +								  /*  Null content means end of Directory */ +#define rfbFileTransferRequest	3 /*  Client asks the server for the transfer of a given file */ +#define rfbFileHeader			4 /*  First packet of a file transfer, containing file's features */ +#define rfbFilePacket			5 /*  One chunk of the file */ +#define rfbEndOfFile			6 /*  End of file transfer (the file has been received or error) */ +#define rfbAbortFileTransfer	7 /*  The file transfer must be aborted, whatever the state */ +#define rfbFileTransferOffer	8 /*  The client offers to send a file to the server */ +#define rfbFileAcceptHeader		9 /*  The server accepts or rejects the file */ +#define rfbCommand				10 /*  The Client sends a simple command (File Delete, Dir create etc...) */ +#define rfbCommandReturn		11 /*  The Client receives the server's answer about a simple command */ +#define rfbFileChecksums		12 /*  The zipped checksums of the destination file (Delta Transfer) */ +#define rfbFileTransferAccess	14 /*  Request FileTransfer authorization */ + +								/*  rfbDirContentRequest client Request - content params  */ +#define rfbRDirContent			1 /*  Request a Server Directory contents */ +#define rfbRDrivesList			2 /*  Request the server's drives list */ +#define rfbRDirRecursiveList	3 /*  Request a server directory content recursive sorted list */ +#define rfbRDirRecursiveSize	4 /*  Request a server directory content recursive size */ + +								/*  rfbDirPacket & rfbCommandReturn  server Answer - content params */ +#define rfbADirectory			1 /*  Reception of a directory name */ +#define rfbAFile				2 /*  Reception of a file name  */ +#define rfbADrivesList			3 /*  Reception of a list of drives */ +#define rfbADirCreate			4 /*  Response to a create dir command  */ +#define rfbADirDelete			5 /*  Response to a delete dir command  */ +#define rfbAFileCreate			6 /*  Response to a create file command  */ +#define rfbAFileDelete			7 /*  Response to a delete file command  */ +#define rfbAFileRename			8 /*  Response to a rename file command  */ +#define rfbADirRename			9 /*  Response to a rename dir command  */ +#define rfbADirRecursiveListItem	10  +#define rfbADirRecursiveSize		11  + +								/*  rfbCommand Command - content params */ +#define rfbCDirCreate			1 /*  Request the server to create the given directory */ +#define rfbCDirDelete			2 /*  Request the server to delete the given directory */ +#define rfbCFileCreate			3 /*  Request the server to create the given file */ +#define rfbCFileDelete			4 /*  Request the server to delete the given file */ +#define rfbCFileRename			5 /*  Request the server to rename the given file  */ +#define rfbCDirRename			6 /*  Request the server to rename the given directory */ + +								/*  Errors - content params or "size" field */ +#define rfbRErrorUnknownCmd     1  /*  Unknown FileTransfer command. */ +#define rfbRErrorCmd			0xFFFFFFFF/*  Error when a command fails on remote side (ret in "size" field) */ + +#define sz_rfbBlockSize			8192  /*  Size of a File Transfer packet (before compression) */ +#define rfbZipDirectoryPrefix   "!UVNCDIR-\0" /*  Transfered directory are zipped in a file with this prefix. Must end with "-" */ +#define sz_rfbZipDirectoryPrefix 9  +#define rfbDirPrefix			"[ " +#define rfbDirSuffix			" ]"		 + + + +/*----------------------------------------------------------------------------- + * Modif sf@2002 + * TextChatMsg - Utilized to order the TextChat mode on server or client + * Bidirectional message + */ + +typedef struct _rfbTextChatMsg { +    uint8_t type;			/* always rfbTextChat */ +    uint8_t pad1;         /*  Could be used later as an additionnal param */ +    uint16_t pad2;		/*  Could be used later as text offset, for instance */ +    uint32_t length;      /*  Specific values for Open, close, finished (-1, -2, -3) */ +    /* followed by char text[length] */ +} rfbTextChatMsg; + +#define sz_rfbTextChatMsg 8 + +#define rfbTextMaxSize		4096 +#define rfbTextChatOpen		0xFFFFFFFF  +#define rfbTextChatClose	0xFFFFFFFE   +#define rfbTextChatFinished 0xFFFFFFFD   + + + +/*----------------------------------------------------------------------------- + * Modif sf@2002 + * ResizeFrameBuffer - The Client must change the size of its framebuffer   + */ + +typedef struct _rfbResizeFrameBufferMsg { +    uint8_t type;			/* always rfbResizeFrameBuffer */ +	uint8_t pad1; +	uint16_t framebufferWidth;	/*  FrameBuffer width */ +	uint16_t framebufferHeigth;	/*  FrameBuffer height */ +} rfbResizeFrameBufferMsg; + +#define sz_rfbResizeFrameBufferMsg 6 + + +/*----------------------------------------------------------------------------- + * Copyright (C) 2001 Harakan Software + * PalmVNC 1.4 & 2.? ResizeFrameBuffer message + * ReSizeFrameBuffer - tell the RFB client to alter its framebuffer, either + * due to a resize of the server desktop or a client-requested scaling factor. + * The pixel format remains unchanged. + */ + +typedef struct { +    uint8_t type;			/* always rfbReSizeFrameBuffer */ +	uint8_t pad1; +	uint16_t desktop_w;	/* Desktop width */ +	uint16_t desktop_h;	/* Desktop height */ +	uint16_t buffer_w;	/* FrameBuffer width */ +	uint16_t buffer_h;	/* Framebuffer height */ +    uint16_t pad2; + +} rfbPalmVNCReSizeFrameBufferMsg; + +#define sz_rfbPalmVNCReSizeFrameBufferMsg (12) + + + + +/*----------------------------------------------------------------------------- + * Union of all server->client messages. + */ + +typedef union { +    uint8_t type; +    rfbFramebufferUpdateMsg fu; +    rfbSetColourMapEntriesMsg scme; +    rfbBellMsg b; +    rfbServerCutTextMsg sct; +	rfbResizeFrameBufferMsg rsfb; +	rfbPalmVNCReSizeFrameBufferMsg prsfb;  +	rfbFileTransferMsg ft; +	rfbTextChatMsg tc; +} rfbServerToClientMsg; + + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * RDV Cache Encoding.   + * special is not used at this point, can be used to reset cache or other specials + * just put it to make sure we don't have to change the encoding again.   + */ + +typedef struct { +    uint16_t special; +} rfbCacheRect; + +#define sz_rfbCacheRect 2 + + + + +/***************************************************************************** + * + * Message definitions (client -> server) + * + *****************************************************************************/ + + +/*----------------------------------------------------------------------------- + * SetPixelFormat - tell the RFB server the format in which the client wants + * pixels sent. + */ + +typedef struct { +    uint8_t type;			/* always rfbSetPixelFormat */ +    uint8_t pad1; +    uint16_t pad2; +    rfbPixelFormat format; +} rfbSetPixelFormatMsg; + +#define sz_rfbSetPixelFormatMsg (sz_rfbPixelFormat + 4) + + +/*----------------------------------------------------------------------------- + * FixColourMapEntries - when the pixel format uses a "colour map", fix + * read-only colour map entries. + * + *    ***************** NOT CURRENTLY SUPPORTED ***************** + */ + +typedef struct { +    uint8_t type;			/* always rfbFixColourMapEntries */ +    uint8_t pad; +    uint16_t firstColour; +    uint16_t nColours; + +    /* Followed by nColours * 3 * uint16_t +       r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */ + +} rfbFixColourMapEntriesMsg; + +#define sz_rfbFixColourMapEntriesMsg 6 + + +/*----------------------------------------------------------------------------- + * SetEncodings - tell the RFB server which encoding types we accept.  Put them + * in order of preference, if we have any.  We may always receive raw + * encoding, even if we don't specify it here. + */ + +typedef struct { +    uint8_t type;			/* always rfbSetEncodings */ +    uint8_t pad; +    uint16_t nEncodings; +    /* followed by nEncodings * uint32_t encoding types */ +} rfbSetEncodingsMsg; + +#define sz_rfbSetEncodingsMsg 4 + + +/*----------------------------------------------------------------------------- + * FramebufferUpdateRequest - request for a framebuffer update.  If incremental + * is true then the client just wants the changes since the last update.  If + * false then it wants the whole of the specified rectangle. + */ + +typedef struct { +    uint8_t type;			/* always rfbFramebufferUpdateRequest */ +    uint8_t incremental; +    uint16_t x; +    uint16_t y; +    uint16_t w; +    uint16_t h; +} rfbFramebufferUpdateRequestMsg; + +#define sz_rfbFramebufferUpdateRequestMsg 10 + + +/*----------------------------------------------------------------------------- + * KeyEvent - key press or release + * + * Keys are specified using the "keysym" values defined by the X Window System. + * For most ordinary keys, the keysym is the same as the corresponding ASCII + * value.  Other common keys are: + * + * BackSpace		0xff08 + * Tab			0xff09 + * Return or Enter	0xff0d + * Escape		0xff1b + * Insert		0xff63 + * Delete		0xffff + * Home			0xff50 + * End			0xff57 + * Page Up		0xff55 + * Page Down		0xff56 + * Left			0xff51 + * Up			0xff52 + * Right		0xff53 + * Down			0xff54 + * F1			0xffbe + * F2			0xffbf + * ...			... + * F12			0xffc9 + * Shift		0xffe1 + * Control		0xffe3 + * Meta			0xffe7 + * Alt			0xffe9 + */ + +typedef struct { +    uint8_t type;			/* always rfbKeyEvent */ +    uint8_t down;			/* true if down (press), false if up */ +    uint16_t pad; +    uint32_t key;			/* key is specified as an X keysym */ +} rfbKeyEventMsg; + +#define sz_rfbKeyEventMsg 8 + + +/*----------------------------------------------------------------------------- + * PointerEvent - mouse/pen move and/or button press. + */ + +typedef struct { +    uint8_t type;			/* always rfbPointerEvent */ +    uint8_t buttonMask;		/* bits 0-7 are buttons 1-8, 0=up, 1=down */ +    uint16_t x; +    uint16_t y; +} rfbPointerEventMsg; + +#define rfbButton1Mask 1 +#define rfbButton2Mask 2 +#define rfbButton3Mask 4 +#define rfbButton4Mask 8 +#define rfbButton5Mask 16 +/* RealVNC 335 method */ +#define rfbWheelUpMask rfbButton4Mask +#define rfbWheelDownMask rfbButton5Mask + +#define sz_rfbPointerEventMsg 6 + + + +/*----------------------------------------------------------------------------- + * ClientCutText - the client has new text in its cut buffer. + */ + +typedef struct { +    uint8_t type;			/* always rfbClientCutText */ +    uint8_t pad1; +    uint16_t pad2; +    uint32_t length; +    /* followed by char text[length] */ +} rfbClientCutTextMsg; + +#define sz_rfbClientCutTextMsg 8 + + + +/*----------------------------------------------------------------------------- + * sf@2002 - Set Server Scale + * SetServerScale - Server must change the scale of the client buffer. + */ + +typedef struct _rfbSetScaleMsg { +    uint8_t type;			/* always rfbSetScale */ +    uint8_t scale;		/* Scale value 1<sv<n */ +    uint16_t pad; +} rfbSetScaleMsg; + +#define sz_rfbSetScaleMsg 4 + + +/*----------------------------------------------------------------------------- + * Copyright (C) 2001 Harakan Software + * PalmVNC 1.4 & 2.? SetScale Factor message  + * SetScaleFactor - tell the RFB server to alter the scale factor for the + * client buffer. + */ +typedef struct { +    uint8_t type;			/* always rfbPalmVNCSetScaleFactor */ + +    uint8_t scale;		/* Scale factor (positive non-zero integer) */ +    uint16_t pad2; +} rfbPalmVNCSetScaleFactorMsg; + +#define sz_rfbPalmVNCSetScaleFactorMsg (4) + + +/*----------------------------------------------------------------------------- + * rdv@2002 - Set input status + * SetServerInput - Server input is dis/enabled + */ + +typedef struct _rfbSetServerInputMsg { +    uint8_t type;			/* always rfbSetScale */ +    uint8_t status;		/* Scale value 1<sv<n */ +    uint16_t pad; +} rfbSetServerInputMsg; + +#define sz_rfbSetServerInputMsg 4 + +/*----------------------------------------------------------------------------- + * rdv@2002 - Set SW + * SetSW - Server SW/full desktop + */ + +typedef struct _rfbSetSWMsg { +    uint8_t type;			/* always rfbSetSW */ +    uint8_t status;		 +    uint16_t x; +    uint16_t y; +} rfbSetSWMsg; + +#define sz_rfbSetSWMsg 6 + + +/*----------------------------------------------------------------------------- + * Union of all client->server messages. + */ + +typedef union { +    uint8_t type; +    rfbSetPixelFormatMsg spf; +    rfbFixColourMapEntriesMsg fcme; +    rfbSetEncodingsMsg se; +    rfbFramebufferUpdateRequestMsg fur; +    rfbKeyEventMsg ke; +    rfbPointerEventMsg pe; +    rfbClientCutTextMsg cct; +	rfbSetScaleMsg ssc; +	rfbPalmVNCSetScaleFactorMsg pssf; +	rfbSetServerInputMsg sim; +	rfbFileTransferMsg ft; +	rfbSetSWMsg sw; +	rfbTextChatMsg tc; +} rfbClientToServerMsg; + +/*  + * vncauth.h - describes the functions provided by the vncauth library. + */ + +#define MAXPWLEN 8 +#define CHALLENGESIZE 16 + +extern int rfbEncryptAndStorePasswd(char *passwd, char *fname); +extern char *rfbDecryptPasswdFromFile(char *fname); +extern void rfbRandomBytes(unsigned char *bytes); +extern void rfbEncryptBytes(unsigned char *bytes, char *passwd); + + +#endif diff --git a/3rdParty/LibVNC/src/rfb/rfbregion.h b/3rdParty/LibVNC/src/rfb/rfbregion.h new file mode 100755 index 0000000..53da667 --- /dev/null +++ b/3rdParty/LibVNC/src/rfb/rfbregion.h @@ -0,0 +1,65 @@ +#ifndef SRAREGION_H +#define SRAREGION_H + +/* -=- SRA - Simple Region Algorithm + * A simple rectangular region implementation. + * Copyright (c) 2001 James "Wez" Weatherall, Johannes E. Schindelin + */ + +/* -=- sraRect */ + +typedef struct _rect { +	int x1; +	int y1; +	int x2; +	int y2; +} sraRect; + +typedef struct sraRegion sraRegion; + +/* -=- Region manipulation functions */ + +extern sraRegion *sraRgnCreate(); +extern sraRegion *sraRgnCreateRect(int x1, int y1, int x2, int y2); +extern sraRegion *sraRgnCreateRgn(const sraRegion *src); + +extern void sraRgnDestroy(sraRegion *rgn); +extern void sraRgnMakeEmpty(sraRegion *rgn); +extern rfbBool sraRgnAnd(sraRegion *dst, const sraRegion *src); +extern void sraRgnOr(sraRegion *dst, const sraRegion *src); +extern rfbBool sraRgnSubtract(sraRegion *dst, const sraRegion *src); + +extern void sraRgnOffset(sraRegion *dst, int dx, int dy); + +extern rfbBool sraRgnPopRect(sraRegion *region, sraRect *rect, +			  unsigned long flags); + +extern unsigned long sraRgnCountRects(const sraRegion *rgn); +extern rfbBool sraRgnEmpty(const sraRegion *rgn); + +extern sraRegion *sraRgnBBox(const sraRegion *src); + +/* -=- rectangle iterator */ + +typedef struct sraRectangleIterator { +  rfbBool reverseX,reverseY; +  int ptrSize,ptrPos; +  struct sraSpan** sPtrs; +} sraRectangleIterator; + +extern sraRectangleIterator *sraRgnGetIterator(sraRegion *s); +extern sraRectangleIterator *sraRgnGetReverseIterator(sraRegion *s,rfbBool reverseX,rfbBool reverseY); +extern rfbBool sraRgnIteratorNext(sraRectangleIterator *i,sraRect *r); +extern void sraRgnReleaseIterator(sraRectangleIterator *i); + +void sraRgnPrint(const sraRegion *s); + +/* -=- Rectangle clipper (for speed) */ + +extern rfbBool sraClipRect(int *x, int *y, int *w, int *h, +			int cx, int cy, int cw, int ch); + +extern rfbBool sraClipRect2(int *x, int *y, int *x2, int *y2, +			int cx, int cy, int cx2, int cy2); + +#endif  | 
 Swift