diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2015-01-13 20:55:31 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2015-01-13 20:57:14 -0600 |
commit | 3ddfecac5c3abf291a5414985ab0c0ac95f2070d (patch) | |
tree | 1bda55828573c8fbfa60915545a865e61a4e2813 /krdc | |
parent | 8b8dfa9704e3238258bbf37d0353362d0606a7a5 (diff) | |
download | tdenetwork-3ddfecac5c3abf291a5414985ab0c0ac95f2070d.tar.gz tdenetwork-3ddfecac5c3abf291a5414985ab0c0ac95f2070d.zip |
Major overhaul/rewrite of the krdc vnc client to use libvncclient
This relates to Bug 2180 among others
Please note that only minimal testing has been performed; some features may not yet work correctly
Diffstat (limited to 'krdc')
-rw-r--r-- | krdc/CMakeLists.txt | 2 | ||||
-rw-r--r-- | krdc/kremoteview.h | 2 | ||||
-rw-r--r-- | krdc/vnc/CMakeLists.txt | 12 | ||||
-rw-r--r-- | krdc/vnc/colour.c | 415 | ||||
-rw-r--r-- | krdc/vnc/d3des.c | 440 | ||||
-rw-r--r-- | krdc/vnc/d3des.h | 51 | ||||
-rw-r--r-- | krdc/vnc/desktop.c | 1613 | ||||
-rw-r--r-- | krdc/vnc/hextile.c | 129 | ||||
-rw-r--r-- | krdc/vnc/kvncview.cpp | 142 | ||||
-rw-r--r-- | krdc/vnc/kvncview.h | 11 | ||||
-rw-r--r-- | krdc/vnc/rfbproto.c | 1335 | ||||
-rw-r--r-- | krdc/vnc/rfbproto.h | 963 | ||||
-rw-r--r-- | krdc/vnc/scaling.cpp | 331 | ||||
-rw-r--r-- | krdc/vnc/sockets.c | 325 | ||||
-rw-r--r-- | krdc/vnc/threads.cpp | 584 | ||||
-rw-r--r-- | krdc/vnc/threads.h | 102 | ||||
-rw-r--r-- | krdc/vnc/tight.c | 610 | ||||
-rw-r--r-- | krdc/vnc/vncauth.c | 161 | ||||
-rw-r--r-- | krdc/vnc/vncauth.h | 30 | ||||
-rw-r--r-- | krdc/vnc/vnctypes.h | 73 | ||||
-rw-r--r-- | krdc/vnc/vncviewer.h | 120 | ||||
-rw-r--r-- | krdc/vnc/zlib.c | 157 |
22 files changed, 760 insertions, 6848 deletions
diff --git a/krdc/CMakeLists.txt b/krdc/CMakeLists.txt index 2ebe9738..a14bd48b 100644 --- a/krdc/CMakeLists.txt +++ b/krdc/CMakeLists.txt @@ -16,6 +16,8 @@ add_subdirectory( rdp ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../libtdevnc + ${CMAKE_CURRENT_BINARY_DIR}/../libtdevnc ${CMAKE_BINARY_DIR} ${TDE_INCLUDE_DIR} ${TQT_INCLUDE_DIRS} diff --git a/krdc/kremoteview.h b/krdc/kremoteview.h index aca3105e..cd5de6df 100644 --- a/krdc/kremoteview.h +++ b/krdc/kremoteview.h @@ -2,6 +2,8 @@ kremoteview.h - widget that shows the remote framebuffer ------------------- begin : Wed Dec 25 23:58:12 CET 2002 + copyright : (C) 2015 by Timothy Pearson + copyright : (C) 2007 by Urs Wolfer copyright : (C) 2002-2003 by Tim Jansen email : tim@tjansen.de ***************************************************************************/ diff --git a/krdc/vnc/CMakeLists.txt b/krdc/vnc/CMakeLists.txt index 60f1c8f1..996d83a9 100644 --- a/krdc/vnc/CMakeLists.txt +++ b/krdc/vnc/CMakeLists.txt @@ -1,5 +1,8 @@ ################################################# # +# (C) 2015 Timothy Pearson +# kb9vqf (AT) pearsoncomputing (DOT) net +# # (C) 2010-2011 Serghei Amelian # serghei (DOT) amelian (AT) gmail.com # @@ -13,6 +16,9 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/../../libtdevnc + ${CMAKE_CURRENT_BINARY_DIR}/../../libtdevnc + ${CMAKE_BINARY_DIR} ${TDE_INCLUDE_DIR} ${TQT_INCLUDE_DIRS} ) @@ -22,6 +28,8 @@ include_directories( tde_add_library( vnc STATIC_PIC AUTOMOC SOURCES - kvncview.cpp threads.cpp colour.c d3des.c desktop.c rfbproto.c sockets.c - vncauth.c vncprefs.ui vnchostpref.cpp + kvncview.cpp scaling.cpp threads.cpp + vncprefs.ui vnchostpref.cpp + LINK + tdevncclient-static ) diff --git a/krdc/vnc/colour.c b/krdc/vnc/colour.c deleted file mode 100644 index 06af4fd3..00000000 --- a/krdc/vnc/colour.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -/* - * colour.c - functions to deal with colour - i.e. RFB pixel formats, X visuals - * and colormaps. Thanks to Grant McDorman for some of the ideas used here. - */ - -#include "vncviewer.h" -#include <limits.h> - - -#define INVALID_PIXEL 0xffffffff -#define MAX_CMAP_SIZE 256 -#define BGR233_SIZE 256 -unsigned long BGR233ToPixel[BGR233_SIZE]; - -Colormap cmap; -Visual *vis; -unsigned int visdepth, visbpp; -Bool allocColorFailed = False; - -static int nBGR233ColoursAllocated; - -static int GetBPPForDepth(int depth); -static void SetupBGR233Map(void); -static void AllocateExactBGR233Colours(void); -static Bool AllocateBGR233Colour(int r, int g, int b); - - -/* - * SetVisualAndCmap() deals with the wonderful world of X "visuals" (which are - * equivalent to the RFB protocol's "pixel format"). Having decided on the - * best visual, it also creates a colormap if necessary, sets the appropriate - * resources on the toplevel widget, and sets up the myFormat structure to - * describe the pixel format in terms that the RFB server will be able to - * understand. - * - * The algorithm for deciding which visual to use is as follows: - * - * If forceOwnCmap is true then we try to use a PseudoColor visual - we first - * see if there's one of the same depth as the RFB server, followed by an 8-bit - * deep one. - * - * If forceTrueColour is true then we try to use a TrueColor visual - if - * requestedDepth is set then it must be of that depth, otherwise any depth - * will be used. - * - * Otherwise, we use the X server's default visual and colormap. If this is - * TrueColor then we just ask the RFB server for this format. If the default - * isn't TrueColor, or if useBGR233 is true, then we ask the RFB server for - * BGR233 pixel format and use a lookup table to translate to the nearest - * colours provided by the X server. - */ - -void -SetVisualAndCmap() -{ - /* just use default visual and colormap */ - - vis = DefaultVisual(dpy,DefaultScreen(dpy)); - visdepth = DefaultDepth(dpy,DefaultScreen(dpy)); - visbpp = GetBPPForDepth(visdepth); - cmap = DefaultColormap(dpy,DefaultScreen(dpy)); - - if (!appData.useBGR233 && (vis->class == TrueColor)) { - - myFormat.bitsPerPixel = visbpp; - myFormat.depth = visdepth; - myFormat.trueColour = 1; - myFormat.bigEndian = (ImageByteOrder(dpy) == MSBFirst); - myFormat.redShift = ffs(vis->red_mask) - 1; - myFormat.greenShift = ffs(vis->green_mask) - 1; - myFormat.blueShift = ffs(vis->blue_mask) - 1; - myFormat.redMax = vis->red_mask >> myFormat.redShift; - myFormat.greenMax = vis->green_mask >> myFormat.greenShift; - myFormat.blueMax = vis->blue_mask >> myFormat.blueShift; - - fprintf(stderr, - "Using default colormap which is TrueColor. Pixel format:\n"); - PrintPixelFormat(&myFormat); - return; - } - - appData.useBGR233 = True; - - myFormat.bitsPerPixel = 8; - myFormat.depth = 8; - myFormat.trueColour = 1; - myFormat.bigEndian = 0; - myFormat.redMax = 7; - myFormat.greenMax = 7; - myFormat.blueMax = 3; - myFormat.redShift = 0; - myFormat.greenShift = 3; - myFormat.blueShift = 6; - - fprintf(stderr, - "Using default colormap and translating from BGR233. Pixel format:\n"); - PrintPixelFormat(&myFormat); - - SetupBGR233Map(); -} - - -/* - * GetBPPForDepth looks through the "pixmap formats" to find the bits-per-pixel - * for the given depth. - */ - -static int -GetBPPForDepth(int depth) -{ - XPixmapFormatValues *format; - int nformats; - int i; - int bpp; - - format = XListPixmapFormats(dpy, &nformats); - - for (i = 0; i < nformats; i++) { - if (format[i].depth == depth) - break; - } - - if (i == nformats) { - fprintf(stderr,"no pixmap format for depth %d???\n", depth); - exit(1); - } - - bpp = format[i].bits_per_pixel; - - XFree(format); - - if (bpp != 1 && bpp != 8 && bpp != 16 && bpp != 32) { - fprintf(stderr,"Can't cope with %d bits-per-pixel. Sorry.\n", bpp); - exit(1); - } - - return bpp; -} - - - -/* - * SetupBGR233Map() sets up the BGR233ToPixel array. - * - * It calls AllocateExactBGR233Colours to allocate some exact BGR233 colours - * (limited by space in the colormap and/or by the value of the nColours - * resource). If the number allocated is less than BGR233_SIZE then it fills - * the rest in using the "nearest" colours available. How this is done depends - * on the value of the useSharedColours resource. If it's false, we use only - * colours from the exact BGR233 colours we've just allocated. If it's true, - * then we also use other clients' "shared" colours available in the colormap. - */ - -static void -SetupBGR233Map(void) -{ - int r, g, b; - long i; - unsigned long nearestPixel = 0; - int cmapSize; - XColor cmapEntry[MAX_CMAP_SIZE]; - Bool exactBGR233[MAX_CMAP_SIZE]; - Bool shared[MAX_CMAP_SIZE]; - Bool usedAsNearest[MAX_CMAP_SIZE]; - int nSharedUsed = 0; - - if (visdepth > 8) { - appData.nColours = 256; /* ignore nColours setting for > 8-bit deep */ - } - - for (i = 0; i < BGR233_SIZE; i++) { - BGR233ToPixel[i] = INVALID_PIXEL; - } - - AllocateExactBGR233Colours(); - - fprintf(stderr,"Got %d exact BGR233 colours out of %d\n", - nBGR233ColoursAllocated, appData.nColours); - - if (nBGR233ColoursAllocated < BGR233_SIZE) { - - if (visdepth > 8) { /* shouldn't get here */ - fprintf(stderr,"Error: couldn't allocate BGR233 colours even though " - "depth is %d\n", visdepth); - exit(1); - } - - cmapSize = (1 << visdepth); - - for (i = 0; i < cmapSize; i++) { - cmapEntry[i].pixel = i; - exactBGR233[i] = False; - shared[i] = False; - usedAsNearest[i] = False; - } - - XQueryColors(dpy, cmap, cmapEntry, cmapSize); - - /* mark all our exact BGR233 pixels */ - - for (i = 0; i < BGR233_SIZE; i++) { - if (BGR233ToPixel[i] != INVALID_PIXEL) - exactBGR233[BGR233ToPixel[i]] = True; - } - - if (appData.useSharedColours) { - - /* Try to find existing shared colours. This is harder than it sounds - because XQueryColors doesn't tell us whether colours are shared, - private or unallocated. What we do is go through the colormap and for - each pixel try to allocate exactly its RGB values. If this returns a - different pixel then it's definitely either a private or unallocated - pixel, so no use to us. If it returns us the same pixel again, then - it's likely that it's a shared colour - however, it is possible that - it was actually an unallocated pixel, which we've now allocated. We - minimise this possibility by going through the pixels in reverse order - - this helps becuse the X server allocates new pixels from the lowest - number up, so it should only be a problem for the lowest unallocated - pixel. Got that? */ - - for (i = cmapSize-1; i >= 0; i--) { - if (!exactBGR233[i] && - XAllocColor(dpy, cmap, &cmapEntry[i])) { - - if (cmapEntry[i].pixel == (unsigned long) i) { - - shared[i] = True; /* probably shared */ - - } else { - - /* "i" is either unallocated or private. We have now unnecessarily - allocated cmapEntry[i].pixel. Free it. */ - - XFreeColors(dpy, cmap, &cmapEntry[i].pixel, 1, 0); - } - } - } - } - - /* Now fill in the nearest colours */ - - for (r = 0; r < 8; r++) { - for (g = 0; g < 8; g++) { - for (b = 0; b < 4; b++) { - if (BGR233ToPixel[(b<<6) | (g<<3) | r] == INVALID_PIXEL) { - - unsigned long minDistance = ULONG_MAX; - - for (i = 0; i < cmapSize; i++) { - if (exactBGR233[i] || shared[i]) { - unsigned long distance - = (abs(cmapEntry[i].red - r * 65535 / 7) - + abs(cmapEntry[i].green - g * 65535 / 7) - + abs(cmapEntry[i].blue - b * 65535 / 3)); - - if (distance < minDistance) { - minDistance = distance; - nearestPixel = i; - } - } - } - - BGR233ToPixel[(b<<6) | (g<<3) | r] = nearestPixel; - if (shared[nearestPixel] && !usedAsNearest[nearestPixel]) - nSharedUsed++; - usedAsNearest[nearestPixel] = True; - } - } - } - } - - /* Tidy up shared colours which we allocated but aren't going to use */ - - for (i = 0; i < cmapSize; i++) { - if (shared[i] && !usedAsNearest[i]) { - XFreeColors(dpy, cmap, (unsigned long *)&i, 1, 0); - } - } - - fprintf(stderr,"Using %d existing shared colours\n", nSharedUsed); - } -} - - -/* - * AllocateExactBGR233Colours() attempts to allocate each of the colours in the - * BGR233 colour cube, stopping when an allocation fails. The order it does - * this in is such that we should get a fairly well spread subset of the cube, - * however many allocations are made. There's probably a neater algorithm for - * doing this, but it's not obvious to me anyway. The way this algorithm works - * is: - * - * At each stage, we introduce a new value for one of the primaries, and - * allocate all the colours with the new value of that primary and all previous - * values of the other two primaries. We start with r=0 as the "new" value - * for r, and g=0, b=0 as the "previous" values of g and b. So we get: - * - * New primary value Previous values of other primaries Colours allocated - * ----------------- ---------------------------------- ----------------- - * r=0 g=0 b=0 r0 g0 b0 - * g=7 r=0 b=0 r0 g7 b0 - * b=3 r=0 g=0,7 r0 g0 b3 - * r0 g7 b3 - * r=7 g=0,7 b=0,3 r7 g0 b0 - * r7 g0 b3 - * r7 g7 b0 - * r7 g7 b3 - * g=3 r=0,7 b=0,3 r0 g3 b0 - * r0 g3 b3 - * r7 g3 b0 - * r7 g3 b3 - * ....etc. - * */ - -static void -AllocateExactBGR233Colours(void) -{ - int rv[] = {0,7,3,5,1,6,2,4}; - int gv[] = {0,7,3,5,1,6,2,4}; - int bv[] = {0,3,1,2}; - int rn = 0; - int gn = 1; - int bn = 1; - int ri, gi, bi; - - nBGR233ColoursAllocated = 0; - - while (1) { - if (rn == 8) - break; - - ri = rn; - for (gi = 0; gi < gn; gi++) { - for (bi = 0; bi < bn; bi++) { - if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) - return; - } - } - rn++; - - if (gn == 8) - break; - - gi = gn; - for (ri = 0; ri < rn; ri++) { - for (bi = 0; bi < bn; bi++) { - if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) - return; - } - } - gn++; - - if (bn < 4) { - - bi = bn; - for (ri = 0; ri < rn; ri++) { - for (gi = 0; gi < gn; gi++) { - if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) - return; - } - } - bn++; - } - } -} - - -/* - * AllocateBGR233Colour() attempts to allocate the given BGR233 colour as a - * shared colormap entry, storing its pixel value in the BGR233ToPixel array. - * r is from 0 to 7, g from 0 to 7 and b from 0 to 3. It fails either when the - * allocation fails or when we would exceed the number of colours specified in - * the nColours resource. - */ - -static Bool -AllocateBGR233Colour(int r, int g, int b) -{ - XColor c; - - if (nBGR233ColoursAllocated >= appData.nColours) - return False; - - c.red = r * 65535 / 7; - c.green = g * 65535 / 7; - c.blue = b * 65535 / 3; - - if (!XAllocColor(dpy, cmap, &c)) - return False; - - BGR233ToPixel[(b<<6) | (g<<3) | r] = c.pixel; - - nBGR233ColoursAllocated++; - - return True; -} diff --git a/krdc/vnc/d3des.c b/krdc/vnc/d3des.c deleted file mode 100644 index 8a358ce6..00000000 --- a/krdc/vnc/d3des.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * 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/krdc/vnc/d3des.h b/krdc/vnc/d3des.h deleted file mode 100644 index ea3da44c..00000000 --- a/krdc/vnc/d3des.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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/krdc/vnc/desktop.c b/krdc/vnc/desktop.c deleted file mode 100644 index 73b2e423..00000000 --- a/krdc/vnc/desktop.c +++ /dev/null @@ -1,1613 +0,0 @@ -/* - * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. - * Copyright (C) 2002 Tim Jansen. All Rights Reserved. - * Copyright (C) 1999-2001 Anders Lindstr�m - * - * - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * tim@tjansen.de: - removed stuff for krdc - * - merged with shm.c and misc.c - * - added FillRectangle and Sync methods to draw only on - * the image - * - added Zoom functionality, based on rotation funcs from - * SGE by Anders Lindstr�m) - * - added support for softcursor encoding - * - */ - -/* - * desktop.c - functions to deal with "desktop" window. - */ - -#include <X11/Xlib.h> -#include <sys/ipc.h> -#include <sys/shm.h> -#include <X11/extensions/XShm.h> -#include <math.h> -#include <limits.h> -#include "vncviewer.h" - -static XShmSegmentInfo shminfo; -static Bool caughtShmError = False; -static Bool needShmCleanup = False; - -static XShmSegmentInfo zoomshminfo; -static Bool caughtZoomShmError = False; -static Bool needZoomShmCleanup = False; - -static Bool gcInited = False; -GC gc; -GC srcGC, dstGC; /* used for debugging copyrect */ -Dimension dpyWidth, dpyHeight; - -static XImage *image = NULL; -Bool useShm = True; - -static Bool zoomActive = False; -static int zoomWidth, zoomHeight; -static XImage *zoomImage = NULL; -static Bool useZoomShm = True; - -/* for softcursor */ -static char *savedArea = NULL; - -typedef enum { - SOFTCURSOR_UNDER, - SOFTCURSOR_PART_UNDER, - SOFTCURSOR_UNAFFECTED -} SoftCursorState; - -typedef int Sint32; -typedef short Sint16; -typedef char Sint8; -typedef unsigned int Uint32; -typedef unsigned short Uint16; -typedef unsigned char Uint8; - -typedef struct { - int w, h; - unsigned int pitch; - void *pixels; - int BytesPerPixel; -} Surface; - -typedef struct { - Sint16 x, y; - Uint16 w, h; -} Rect; - -static void bgr233cpy(CARD8 *dst, CARD8 *src, int len); -static void CopyDataToScreenRaw(char *buf, int x, int y, int width, int height); -static void CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width,int height); -static void FillRectangleBGR233(CARD8 buf, int x, int y, int width,int height); -static int CheckRectangle(int x, int y, int width, int height); -static SoftCursorState getSoftCursorState(int x, int y, int width, int height); -static void discardCursorSavedArea(void); -static void saveCursorSavedArea(void); - -static void ZoomInit(void); -static void transformZoomSrc(int six, int siy, int siw, int sih, - int *dix, int *diy, int *diw, int *dih, - int srcW, int dstW, int srcH, int dstH); -static void transformZoomDst(int *six, int *siy, int *siw, int *sih, - int dix, int diy, int diw, int dih, - int srcW, int dstW, int srcH, int dstH); -static void ZoomSurfaceSrcCoords(int x, int y, int w, int h, - int *dix, int *diy, int *diw, int *dih, - Surface * src, Surface * dst); -static void ZoomSurfaceCoords32(int sx, int sy, int sw, int sh, - int dx, int dy, Surface * src, Surface * dst); -static void sge_transform(Surface *src, Surface *dst, float xscale, float yscale, - Uint16 qx, Uint16 qy); - - -void -DesktopInit(Window win) -{ - XGCValues gcv; - - image = CreateShmImage(); - - if (!image) { - useShm = False; - image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, - si.framebufferWidth, si.framebufferHeight, - BitmapPad(dpy), 0); - - image->data = calloc(image->bytes_per_line * image->height, 1); - if (!image->data) { - fprintf(stderr,"malloc failed\n"); - exit(1); - } - } - - gc = XCreateGC(dpy,win,0,NULL); - - gcv.function = GXxor; - gcv.foreground = 0x0f0f0f0f; - srcGC = XCreateGC(dpy,win,GCFunction|GCForeground,&gcv); - gcv.foreground = 0xf0f0f0f0; - dstGC = XCreateGC(dpy,win,GCFunction|GCForeground,&gcv); - gcInited = True; -} - -/* - * DrawScreenRegionX11Thread - * Never call from any other desktop.c function, only for X11 thread - */ - -void -DrawScreenRegionX11Thread(Window win, int x, int y, int width, int height) { - zoomActive = False; - zoomWidth = 0; - zoomHeight = 0; - - if (!image) - return; - - if (useShm) - XShmPutImage(dpy, win, gc, image, x, y, x, y, width, height, False); - else - XPutImage(dpy, win, gc, image, x, y, x, y, width, height); -} - -/* - * CheckRectangle - */ - -static int CheckRectangle(int x, int y, int width, int height) { - if ((x < 0) || (y < 0)) - return 0; - - if (((x+width) > si.framebufferWidth) || ((y+height) > si.framebufferHeight)) - return 0; - - return 1; -} - -static -void bgr233cpy(CARD8 *dst, CARD8 *src, int len) { - int i; - CARD16 *d16; - CARD32 *d32; - - switch (visbpp) { - case 8: - for (i = 0; i < len; i++) - *(dst++) = (CARD8) BGR233ToPixel[*(src++)]; - break; - case 16: - d16 = (CARD16*) dst; - for (i = 0; i < len; i++) - *(d16++) = (CARD16) BGR233ToPixel[*(src++)]; - break; - case 32: - d32 = (CARD32*) dst; - for (i = 0; i < len; i++) - *(d32++) = (CARD32) BGR233ToPixel[*(src++)]; - break; - default: - fprintf(stderr, "Unsupported softcursor depth %d\n", visbpp); - } -} - - -/* - * CopyDataToScreen. - */ - -void -CopyDataToScreen(char *buf, int x, int y, int width, int height) -{ - SoftCursorState s; - - if (!CheckRectangle(x, y, width, height)) - return; - - LockFramebuffer(); - s = getSoftCursorState(x, y, width, height); - if (s == SOFTCURSOR_PART_UNDER) - undrawCursor(); - - if (!appData.useBGR233) - CopyDataToScreenRaw(buf, x, y, width, height); - else - CopyBGR233ToScreen((CARD8 *)buf, x, y, width, height); - - if (s != SOFTCURSOR_UNAFFECTED) - drawCursor(); - - UnlockFramebuffer(); - SyncScreenRegion(x, y, width, height); -} - -/* - * CopyDataToScreenRaw. - */ - -static void -CopyDataToScreenRaw(char *buf, int x, int y, int width, int height) -{ - int h; - int widthInBytes = width * visbpp / 8; - int scrWidthInBytes = image->bytes_per_line; - char *scr = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - - for (h = 0; h < height; h++) { - memcpy(scr, buf, widthInBytes); - buf += widthInBytes; - scr += scrWidthInBytes; - } -} - -/* - * CopyBGR233ToScreen. - */ - -static void -CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height) -{ - int p, q; - int xoff = 7 - (x & 7); - int xcur; - int fbwb = si.framebufferWidth / 8; - CARD8 *scr1 = ((CARD8 *)image->data) + y * fbwb + x / 8; - CARD8 *scrt; - CARD8 *scr8 = ((CARD8 *)image->data) + y * si.framebufferWidth + x; - CARD16 *scr16 = ((CARD16 *)image->data) + y * si.framebufferWidth + x; - CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x; - - switch (visbpp) { - - /* thanks to Chris Hooper for single bpp support */ - - case 1: - for (q = 0; q < height; q++) { - xcur = xoff; - scrt = scr1; - for (p = 0; p < width; p++) { - *scrt = ((*scrt & ~(1 << xcur)) - | (BGR233ToPixel[*(buf++)] << xcur)); - - if (xcur-- == 0) { - xcur = 7; - scrt++; - } - } - scr1 += fbwb; - } - break; - - case 8: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr8++) = BGR233ToPixel[*(buf++)]; - } - scr8 += si.framebufferWidth - width; - } - break; - - case 16: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr16++) = BGR233ToPixel[*(buf++)]; - } - scr16 += si.framebufferWidth - width; - } - break; - - case 32: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr32++) = BGR233ToPixel[*(buf++)]; - } - scr32 += si.framebufferWidth - width; - } - break; - } -} - -/* - * FillRectangle8. - */ - -void -FillRectangle8(CARD8 fg, int x, int y, int width, int height) -{ - SoftCursorState s; - - if (!CheckRectangle(x, y, width, height)) - return; - - s = getSoftCursorState(x, y, width, height); - if (s == SOFTCURSOR_PART_UNDER) - undrawCursor(); - - if (!appData.useBGR233) { - int h; - int widthInBytes = width * visbpp / 8; - int scrWidthInBytes = image->bytes_per_line; - - char *scr = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - - for (h = 0; h < height; h++) { - memset(scr, fg, widthInBytes); - scr += scrWidthInBytes; - } - } else { - FillRectangleBGR233(fg, x, y, width, height); - } - - if (s != SOFTCURSOR_UNAFFECTED) - drawCursor(); -} - -/* - * FillRectangleBGR233. - */ - -static void -FillRectangleBGR233(CARD8 fg, int x, int y, int width, int height) -{ - int p, q; - int xoff = 7 - (x & 7); - int xcur; - int fbwb = si.framebufferWidth / 8; - CARD8 *scr1 = ((CARD8 *)image->data) + y * fbwb + x / 8; - CARD8 *scrt; - CARD8 *scr8 = ((CARD8 *)image->data) + y * si.framebufferWidth + x; - CARD16 *scr16 = ((CARD16 *)image->data) + y * si.framebufferWidth + x; - CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x; - - unsigned long fg233 = BGR233ToPixel[fg]; - - switch (visbpp) { - - /* thanks to Chris Hooper for single bpp support */ - - case 1: - for (q = 0; q < height; q++) { - xcur = xoff; - scrt = scr1; - for (p = 0; p < width; p++) { - *scrt = ((*scrt & ~(1 << xcur)) - | (fg233 << xcur)); - - if (xcur-- == 0) { - xcur = 7; - scrt++; - } - } - scr1 += fbwb; - } - break; - - case 8: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr8++) = fg233; - } - scr8 += si.framebufferWidth - width; - } - break; - - case 16: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr16++) = fg233; - } - scr16 += si.framebufferWidth - width; - } - break; - - case 32: - for (q = 0; q < height; q++) { - for (p = 0; p < width; p++) { - *(scr32++) = fg233; - } - scr32 += si.framebufferWidth - width; - } - break; - } -} - -/* - * FillRectangle16 - */ - -void -FillRectangle16(CARD16 fg, int x, int y, int width, int height) -{ - int i, h; - int scrWidthInBytes = image->bytes_per_line; - - char *scr = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - CARD16 *scr16; - SoftCursorState s; - - if (!CheckRectangle(x, y, width, height)) - return; - - s = getSoftCursorState(x, y, width, height); - if (s == SOFTCURSOR_PART_UNDER) - undrawCursor(); - - for (h = 0; h < height; h++) { - scr16 = (CARD16*) scr; - for (i = 0; i < width; i++) - scr16[i] = fg; - scr += scrWidthInBytes; - } - - if (s != SOFTCURSOR_UNAFFECTED) - drawCursor(); -} - -/* - * FillRectangle32 - */ - -void -FillRectangle32(CARD32 fg, int x, int y, int width, int height) -{ - int i, h; - int scrWidthInBytes = image->bytes_per_line; - SoftCursorState s; - - char *scr = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - CARD32 *scr32; - - if (!CheckRectangle(x, y, width, height)) - return; - - s = getSoftCursorState(x, y, width, height); - if (s == SOFTCURSOR_PART_UNDER) - undrawCursor(); - - for (h = 0; h < height; h++) { - scr32 = (CARD32*) scr; - for (i = 0; i < width; i++) - scr32[i] = fg; - scr += scrWidthInBytes; - } - - if (s != SOFTCURSOR_UNAFFECTED) - drawCursor(); -} - -/* - * CopyDataFromScreen. - */ - -void -CopyDataFromScreen(char *buf, int x, int y, int width, int height) -{ - int widthInBytes = width * visbpp / 8; - int scrWidthInBytes = image->bytes_per_line; - char *src = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - int h; - - if (!CheckRectangle(x, y, width, height)) - return; - - for (h = 0; h < height; h++) { - memcpy(buf, src, widthInBytes); - src += scrWidthInBytes; - buf += widthInBytes; - } -} - -/* - * CopyArea - */ - -void -CopyArea(int srcX, int srcY, int width, int height, int x, int y) -{ - int widthInBytes = width * visbpp / 8; - SoftCursorState sSrc, sDst; - - LockFramebuffer(); - sSrc = getSoftCursorState(srcX, srcY, width, height); - sDst = getSoftCursorState(x, y, width, height); - if ((sSrc != SOFTCURSOR_UNAFFECTED) || - (sDst == SOFTCURSOR_PART_UNDER)) - undrawCursor(); - - if ((srcY+height < y) || (y+height < srcY) || - (srcX+width < x) || (x+width < srcX)) { - - int scrWidthInBytes = image->bytes_per_line; - char *src = (image->data + srcY * scrWidthInBytes - + srcX * visbpp / 8); - char *dst = (image->data + y * scrWidthInBytes - + x * visbpp / 8); - int h; - - if (!CheckRectangle(srcX, srcY, width, height)) { - UnlockFramebuffer(); - return; - } - if (!CheckRectangle(x, y, width, height)) { - UnlockFramebuffer(); - return; - } - - for (h = 0; h < height; h++) { - memcpy(dst, src, widthInBytes); - src += scrWidthInBytes; - dst += scrWidthInBytes; - } - } - else { - char *buf = malloc(widthInBytes*height); - if (!buf) { - UnlockFramebuffer(); - fprintf(stderr, "Out of memory, CopyArea impossible\n"); - return; - } - CopyDataFromScreen(buf, srcX, srcY, width, height); - CopyDataToScreenRaw(buf, x, y, width, height); - free(buf); - } - if ((sSrc != SOFTCURSOR_UNAFFECTED) || - (sDst != SOFTCURSOR_UNAFFECTED)) - drawCursor(); - UnlockFramebuffer(); - SyncScreenRegion(x, y, width, height); -} - -void SyncScreenRegion(int x, int y, int width, int height) { - int dx, dy, dw, dh; - - if (zoomActive) { - Surface src, dest; - src.w = si.framebufferWidth; - src.h = si.framebufferHeight; - src.pitch = image->bytes_per_line; - src.pixels = image->data; - src.BytesPerPixel = visbpp / 8; - dest.w = zoomWidth; - dest.h = zoomHeight; - dest.pitch = zoomImage->bytes_per_line; - dest.pixels = zoomImage->data; - dest.BytesPerPixel = visbpp / 8; - ZoomSurfaceSrcCoords(x, y, width, height, &dx, &dy, &dw, &dh, &src, &dest); - } - else { - dx = x; dy = y; - dw = width; dh = height; - } - DrawScreenRegion(dx, dy, dw, dh); -} - -void SyncScreenRegionX11Thread(int x, int y, int width, int height) { - int dx, dy, dw, dh; - - if (zoomActive) { - Surface src, dest; - src.w = si.framebufferWidth; - src.h = si.framebufferHeight; - src.pitch = image->bytes_per_line; - src.pixels = image->data; - src.BytesPerPixel = visbpp / 8; - dest.w = zoomWidth; - dest.h = zoomHeight; - dest.pitch = zoomImage->bytes_per_line; - dest.pixels = zoomImage->data; - dest.BytesPerPixel = visbpp / 8; - ZoomSurfaceSrcCoords(x, y, width, height, &dx, &dy, &dw, &dh, &src, &dest); - } - else { - dx = x; dy = y; - dw = width; dh = height; - } - DrawAnyScreenRegionX11Thread(dx, dy, dw, dh); -} - -/* - * ToplevelInitBeforeRealization sets the title, geometry and other resources - * on the toplevel window. - */ - -void -ToplevelInit() -{ - dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy)); - dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy)); -} - -/* - * Cleanup - perform shm cleanup operations prior to exiting. - */ - -void -Cleanup() -{ - if (useShm || useZoomShm) - ShmCleanup(); -} - -void -ShmCleanup() -{ - fprintf(stderr,"ShmCleanup called\n"); - if (needShmCleanup) { - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid, IPC_RMID, 0); - needShmCleanup = False; - } - if (needZoomShmCleanup) { - shmdt(zoomshminfo.shmaddr); - shmctl(zoomshminfo.shmid, IPC_RMID, 0); - needZoomShmCleanup = False; - } -} - -static int -ShmCreationXErrorHandler(Display *d, XErrorEvent *e) -{ - caughtShmError = True; - return 0; -} - -XImage * -CreateShmImage() -{ - XImage *_image; - XErrorHandler oldXErrorHandler; - - if (!XShmQueryExtension(dpy)) - return NULL; - - _image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &shminfo, - si.framebufferWidth, si.framebufferHeight); - if (!_image) return NULL; - - shminfo.shmid = shmget(IPC_PRIVATE, - _image->bytes_per_line * _image->height, - IPC_CREAT|0777); - - if (shminfo.shmid == -1) { - XDestroyImage(_image); - return NULL; - } - - shminfo.shmaddr = _image->data = shmat(shminfo.shmid, 0, 0); - - if (shminfo.shmaddr == (char *)-1) { - XDestroyImage(_image); - shmctl(shminfo.shmid, IPC_RMID, 0); - return NULL; - } - - shminfo.readOnly = True; - - oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler); - XShmAttach(dpy, &shminfo); - XSync(dpy, False); - XSetErrorHandler(oldXErrorHandler); - - if (caughtShmError) { - XDestroyImage(_image); - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid, IPC_RMID, 0); - return NULL; - } - - needShmCleanup = True; - - fprintf(stderr,"Using shared memory PutImage\n"); - - return _image; -} - -void undrawCursor() { - int x, y, w, h; - - if ((imageIndex < 0) || !savedArea) - return; - - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &x, &y, &w, &h); - - if ((w < 1) || (h < 1)) - return; - - CopyDataToScreenRaw(savedArea, x, y, w, h); - discardCursorSavedArea(); -} - -static void drawCursorImage() { - int x, y, w, h, pw, pixelsLeft, processingMask; - int skipLeft, skipRight; - PointerImage *pi = &pointerImages[imageIndex]; - CARD8 *img = (CARD8*) pi->image; - CARD8 *imgEnd = &img[pi->len]; - CARD8 *fb; - - /* check whether the source image has ended (image broken) */ -#define CHECK_IMG(x) if (&img[x] > imgEnd) goto imgError - -/* check whether the end of the framebuffer has been reached (last line) */ -#define CHECK_END() if ((wl == 0) && (h == 1)) return - -/* skip x pixels in the source (x must be < pixelsLeft!) */ -#define SKIP_IMG(x) if ((x > 0) && !processingMask) { \ - CHECK_END(); \ - img += pw * x; \ - CHECK_IMG(0); \ - } - -/* skip x pixels in source and destination */ -#define SKIP_PIXELS(x) { int wl = x; \ - while (pixelsLeft <= wl) { \ - wl -= pixelsLeft; \ - SKIP_IMG(pixelsLeft); \ - CHECK_END(); \ - pixelsLeft = *(img++); \ - CHECK_IMG(0); \ - processingMask = processingMask ? 0 : 1; \ - } \ - pixelsLeft -= wl; \ - SKIP_IMG(wl); \ - } - - if (!img) - return; - - x = cursorX - pi->hotX; - y = cursorY - pi->hotY; - w = pi->w; - h = pi->h; - - if (!rectsIntersect(x, y, w, h, - 0, 0, si.framebufferWidth, si.framebufferHeight)) { - fprintf(stderr, "intersect abort\n"); - return; - } - - pw = myFormat.bitsPerPixel / 8; - processingMask = 1; - pixelsLeft = *(img++); - -/* at this point everything is initialized for the macros */ - - /* skip/clip bottom lines */ - if ((y+h) > si.framebufferHeight) - h = si.framebufferHeight - y; - - /* Skip invisible top lines */ - while (y < 0) { - SKIP_PIXELS(w); - y++; - h--; - } - - /* calculate left/right clipping */ - if (x < 0) { - skipLeft = -x; - w += x; - x = 0; - } - else - skipLeft = 0; - - if ((x+w) > si.framebufferWidth) { - skipRight = (x+w) - si.framebufferWidth; - w = si.framebufferWidth - x; - } - else - skipRight = 0; - - fb = (CARD8*) image->data + y * image->bytes_per_line + x * visbpp / 8; - - /* Paint the thing */ - while (h > 0) { - SKIP_PIXELS(skipLeft); - - { - CARD8 *fbx = fb; - int wl = w; - while (pixelsLeft <= wl) { - wl -= pixelsLeft; - if ((pixelsLeft > 0) && !processingMask) { - int pl = pw * pixelsLeft; - CHECK_IMG(pl); - if (!appData.useBGR233) - memcpy(fbx, img, pl); - else - bgr233cpy(fbx, img, pixelsLeft); - img += pl; - } - - CHECK_END(); - fbx += pixelsLeft * visbpp / 8; - pixelsLeft = *(img++); - - CHECK_IMG(0); - processingMask = processingMask ? 0 : 1; - } - pixelsLeft -= wl; - if ((wl > 0) && !processingMask) { - int pl = pw * wl; - CHECK_IMG(pl); - if (!appData.useBGR233) - memcpy(fbx, img, pl); - else - bgr233cpy(fbx, img, wl); - img += pl; - } - } - - SKIP_PIXELS(skipRight); - fb += image->bytes_per_line; - h--; - } - return; - -imgError: - fprintf(stderr, "Error in softcursor image %d\n", imageIndex); - pointerImages[imageIndex].set = 0; -} - -static void discardCursorSavedArea() { - if (savedArea) - free(savedArea); - savedArea = 0; -} - -static void saveCursorSavedArea() { - int x, y, w, h; - - if (imageIndex < 0) - return; - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &x, &y, &w, &h); - if ((w < 1) || (h < 1)) - return; - discardCursorSavedArea(); - savedArea = malloc(h*image->bytes_per_line); - if (!savedArea) { - fprintf(stderr,"malloc failed, saving cursor not possible\n"); - exit(1); - } - CopyDataFromScreen(savedArea, x, y, w, h); -} - -void drawCursor() { - saveCursorSavedArea(); - drawCursorImage(); -} - -void getBoundingRectCursor(int cx, int cy, int _imageIndex, - int *x, int *y, int *w, int *h) { - int nx, ny, nw, nh; - - if ((_imageIndex < 0) || !pointerImages[_imageIndex].set) { - *x = 0; - *y = 0; - *w = 0; - *h = 0; - return; - } - - nx = cx - pointerImages[_imageIndex].hotX; - ny = cy - pointerImages[_imageIndex].hotY; - nw = pointerImages[_imageIndex].w; - nh = pointerImages[_imageIndex].h; - if (nx < 0) { - nw += nx; - nx = 0; - } - if (ny < 0) { - nh += ny; - ny = 0; - } - if ((nx+nw) > si.framebufferWidth) - nw = si.framebufferWidth - nx; - if ((ny+nh) > si.framebufferHeight) - nh = si.framebufferHeight - ny; - if ((nw <= 0) || (nh <= 0)) { - *x = 0; - *y = 0; - *w = 0; - *h = 0; - return; - } - - *x = nx; - *y = ny; - *w = nw; - *h = nh; -} - -static SoftCursorState getSoftCursorState(int x, int y, int w, int h) { - int cx, cy, cw, ch; - - if (imageIndex < 0) - return SOFTCURSOR_UNAFFECTED; - - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &cx, &cy, &cw, &ch); - - if ((cw == 0) || (ch == 0)) - return SOFTCURSOR_UNAFFECTED; - - if (!rectsIntersect(x, y, w, h, cx, cy, cw, ch)) - return SOFTCURSOR_UNAFFECTED; - if (rectContains(x, y, w, h, cx, cy, cw, ch)) - return SOFTCURSOR_UNDER; - else - return SOFTCURSOR_PART_UNDER; -} - -int rectsIntersect(int x, int y, int w, int h, - int x2, int y2, int w2, int h2) { - if (x2 >= (x+w)) - return 0; - if (y2 >= (y+h)) - return 0; - if ((x2+w2) <= x) - return 0; - if ((y2+h2) <= y) - return 0; - return 1; -} - -int rectContains(int outX, int outY, int outW, int outH, - int inX, int inY, int inW, int inH) { - if (inX < outX) - return 0; - if (inY < outY) - return 0; - if ((inX+inW) > (outX+outW)) - return 0; - if ((inY+inH) > (outY+outH)) - return 0; - return 1; -} - -void rectsJoin(int *nx1, int *ny1, int *nw1, int *nh1, - int x2, int y2, int w2, int h2) { - int ox, oy, ow, oh; - ox = *nx1; - oy = *ny1; - ow = *nw1; - oh = *nh1; - - if (x2 < ox) { - ow += ox - x2; - ox = x2; - } - if (y2 < oy) { - oh += oy - y2; - oy = y2; - } - if ((x2+w2) > (ox+ow)) - ow = (x2+w2) - ox; - if ((y2+h2) > (oy+oh)) - oh = (y2+h2) - oy; - - *nx1 = ox; - *ny1 = oy; - *nw1 = ow; - *nh1 = oh; -} - -XImage * -CreateShmZoomImage() -{ - XImage *_image; - XErrorHandler oldXErrorHandler; - - if (!XShmQueryExtension(dpy)) - return NULL; - - _image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &zoomshminfo, - si.framebufferWidth, si.framebufferHeight); - if (!_image) return NULL; - - zoomshminfo.shmid = shmget(IPC_PRIVATE, - _image->bytes_per_line * _image->height, - IPC_CREAT|0777); - - if (zoomshminfo.shmid == -1) { - XDestroyImage(_image); - return NULL; - } - - zoomshminfo.shmaddr = _image->data = shmat(zoomshminfo.shmid, 0, 0); - - if (zoomshminfo.shmaddr == (char *)-1) { - XDestroyImage(_image); - shmctl(zoomshminfo.shmid, IPC_RMID, 0); - return NULL; - } - - zoomshminfo.readOnly = True; - - oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler); - XShmAttach(dpy, &zoomshminfo); - XSync(dpy, False); - XSetErrorHandler(oldXErrorHandler); - - if (caughtZoomShmError) { - XDestroyImage(_image); - shmdt(zoomshminfo.shmaddr); - shmctl(zoomshminfo.shmid, IPC_RMID, 0); - return NULL; - } - - needZoomShmCleanup = True; - - fprintf(stderr,"Using shared memory PutImage\n"); - - return _image; -} - - -/* - * DrawZoomedScreenRegionX11Thread - * Never call from any other desktop.c function, only for X11 thread - */ - -void -DrawZoomedScreenRegionX11Thread(Window win, int zwidth, int zheight, - int x, int y, int width, int height) { - if (!image) - return; - - if (zwidth > si.framebufferWidth) - zwidth = si.framebufferWidth; - if (zheight > si.framebufferHeight) - zheight = si.framebufferHeight; - - if (!zoomActive) { - ZoomInit(); - zoomActive = True; - } - - if ((zoomWidth != zwidth) || (zoomHeight != zheight)) { - Surface src, dest; - - zoomWidth = zwidth; - zoomHeight = zheight; - - src.w = si.framebufferWidth; - src.h = si.framebufferHeight; - src.pitch = image->bytes_per_line; - src.pixels = image->data; - src.BytesPerPixel = visbpp / 8; - dest.w = zwidth; - dest.h = zheight; - dest.pitch = zoomImage->bytes_per_line; - dest.pixels = zoomImage->data; - dest.BytesPerPixel = visbpp / 8; - sge_transform(&src, &dest, - (float)dest.w/(float)src.w, (float)dest.h/(float)src.h, - 0, 0); - - if (useZoomShm) - XShmPutImage(dpy, win, gc, zoomImage, 0, 0, 0, 0, zwidth, zheight, False); - else - XPutImage(dpy, win, gc, zoomImage, 0, 0, 0, 0, zwidth, zheight); - return; - } - - if (useZoomShm) - XShmPutImage(dpy, win, gc, zoomImage, x, y, x, y, width, height, False); - else - XPutImage(dpy, win, gc, zoomImage, x, y, x, y, width, height); -} - - -static void -ZoomInit() -{ - if (zoomImage) - return; - - zoomImage = CreateShmZoomImage(); - - if (!zoomImage) { - useZoomShm = False; - zoomImage = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, - si.framebufferWidth, si.framebufferHeight, - BitmapPad(dpy), 0); - - zoomImage->data = calloc(zoomImage->bytes_per_line * zoomImage->height, 1); - if (!zoomImage->data) { - fprintf(stderr,"malloc failed\n"); - exit(1); - } - } -} - -static void transformZoomSrc(int six, int siy, int siw, int sih, - int *dix, int *diy, int *diw, int *dih, - int srcW, int dstW, int srcH, int dstH) { - double sx, sy, sw, sh; - double dx, dy, dw, dh; - double wq, hq; - - sx = six; sy = siy; - sw = siw; sh = sih; - - wq = ((double)dstW) / (double) srcW; - hq = ((double)dstH) / (double) srcH; - - dx = sx * wq; - dy = sy * hq; - dw = sw * wq; - dh = sh * hq; - - *dix = dx; - *diy = dy; - *diw = dw+(dx-(int)dx)+0.5; - *dih = dh+(dy-(int)dy)+0.5; -} - -static void transformZoomDst(int *six, int *siy, int *siw, int *sih, - int dix, int diy, int diw, int dih, - int srcW, int dstW, int srcH, int dstH) { - double sx, sy, sw, sh; - double dx, dy, dw, dh; - double wq, hq; - - dx = dix; dy = diy; - dw = diw; dh = dih; - - wq = ((double)dstW) / (double) srcW; - hq = ((double)dstH) / (double) srcH; - - sx = dx / wq; - sy = dy / hq; - sw = dw / wq; - sh = dh / hq; - - *six = sx; - *siy = sy; - *siw = sw+(sx-(int)sx)+0.5; - *sih = sh+(sy-(int)sy)+0.5; -} - - -static void ZoomSurfaceSrcCoords(int six, int siy, int siw, int sih, - int *dix, int *diy, int *diw, int *dih, - Surface * src, Surface * dst) -{ - int dx, dy, dw, dh; - int sx, sy, sw, sh; - - transformZoomSrc(six, siy, siw, sih, - &dx, &dy, &dw, &dh, - src->w, dst->w, src->h, dst->h); - dx-=2; - dy-=2; - dw+=4; - dh+=4; - - if (dx < 0) - dx = 0; - if (dy < 0) - dy = 0; - if (dx+dw > dst->w) - dw = dst->w - dx; - if (dy+dh > dst->h) - dh = dst->h - dy; - - transformZoomDst(&sx, &sy, &sw, &sh, - dx, dy, dw, dh, - src->w, dst->w, src->h, dst->h); - - if (sx+sw > src->w) - sw = src->w - sx; - if (sy+sh > src->h) - sh = src->h - sy; - - ZoomSurfaceCoords32(sx, sy, sw, sh, dx, dy, src, dst); - - *dix = dx; - *diy = dy; - *diw = dw; - *dih = dh; -} - -static void ZoomSurfaceCoords32(int sx, int sy, int sw, int sh, - int dx, int dy, - Surface * src, Surface * dst) -{ - Surface s2; - - s2 = *src; - s2.pixels = ((char*)s2.pixels) + (sx * s2.BytesPerPixel) + (sy * src->pitch); - s2.w = sw; - s2.h = sh; - sge_transform(&s2, dst, - (float)dst->w/(float)src->w, (float)dst->h/(float)src->h, - dx, dy); -} - - -#define sge_clip_xmin(pnt) 0 -#define sge_clip_xmax(pnt) pnt->w -#define sge_clip_ymin(pnt) 0 -#define sge_clip_ymax(pnt) pnt->h - -/*================================================================================== -// Helper function to sge_transform() -// Returns the bounding box -//================================================================================== -*/ -static void _calcRect(Surface *src, Surface *dst, float xscale, float yscale, - Uint16 qx, Uint16 qy, - Sint16 *xmin, Sint16 *ymin, Sint16 *xmax, Sint16 *ymax) -{ - Sint16 x, y, rx, ry; - int i; - - /* Clip to src surface */ - Sint16 sxmin = sge_clip_xmin(src); - Sint16 sxmax = sge_clip_xmax(src); - Sint16 symin = sge_clip_ymin(src); - Sint16 symax = sge_clip_ymax(src); - Sint16 sx[5]; - Sint16 sy[4]; - - /* We don't really need fixed-point here - * but why not? */ - Sint32 ictx = (Sint32) (xscale * 8192.0); - Sint32 icty = (Sint32) (yscale * 8192.0); - - sx[0] = sxmin; - sx[1] = sxmax; - sx[2] = sxmin; - sx[3] = sxmax; - sy[0] = symin; - sy[1] = symax; - sy[2] = symax; - sy[3] = symin; - - /* Calculate the four corner points */ - for(i=0; i<4; i++){ - rx = sx[i]; - ry = sy[i]; - - x = (Sint16)(((ictx*rx) >> 13) + qx); - y = (Sint16)(((icty*ry) >> 13) + qy); - - - if(i==0){ - *xmax = *xmin = x; - *ymax = *ymin = y; - }else{ - if(x>*xmax) - *xmax=x; - else if(x<*xmin) - *xmin=x; - - if(y>*ymax) - *ymax=y; - else if(y<*ymin) - *ymin=y; - } - } - - /* Better safe than sorry...*/ - *xmin -= 1; - *ymin -= 1; - *xmax += 1; - *ymax += 1; - - /* Clip to dst surface */ - if( !dst ) - return; - if( *xmin < sge_clip_xmin(dst) ) - *xmin = sge_clip_xmin(dst); - if( *xmax > sge_clip_xmax(dst) ) - *xmax = sge_clip_xmax(dst); - if( *ymin < sge_clip_ymin(dst) ) - *ymin = sge_clip_ymin(dst); - if( *ymax > sge_clip_ymax(dst) ) - *ymax = sge_clip_ymax(dst); -} - - -/*================================================================================== -** Scale by scale and place at position (qx,qy). -** -** -** Developed with the help from Terry Hancock (hancock@earthlink.net) -** -**==================================================================================*/ -/* First we need some macros to handle different bpp - * I'm sorry about this... - */ -#define TRANSFORM(UintXX, DIV) \ - Sint32 src_pitch=src->pitch/DIV; \ - Sint32 dst_pitch=dst->pitch/DIV; \ - UintXX *src_row = (UintXX *)src->pixels; \ - UintXX *dst_row; \ -\ - for (y=ymin; y<ymax; y++){ \ - dy = y - qy; \ -\ - sx = (Sint32)ctdx; /* Compute source anchor points */ \ - sy = (Sint32)(cty*dy); \ -\ - /* Calculate pointer to dst surface */ \ - dst_row = (UintXX *)dst->pixels + y*dst_pitch; \ -\ - for (x=xmin; x<xmax; x++){ \ - rx=(Sint16)(sx >> 13); /* Convert from fixed-point */ \ - ry=(Sint16)(sy >> 13); \ -\ - /* Make sure the source pixel is actually in the source image. */ \ - if( (rx>=sxmin) && (rx<sxmax) && (ry>=symin) && (ry<symax) ) \ - *(dst_row + x) = *(src_row + ry*src_pitch + rx); \ -\ - sx += ctx; /* Incremental transformations */ \ - } \ - } - - -/* Interpolated transform */ -#define TRANSFORM_AA(UintXX, DIV) \ - Sint32 src_pitch=src->pitch/DIV; \ - Sint32 dst_pitch=dst->pitch/DIV; \ - UintXX *src_row = (UintXX *)src->pixels; \ - UintXX *dst_row; \ - UintXX c1, c2, c3, c4;\ - Uint32 R, G, B, A=0; \ - UintXX Rmask = image->red_mask;\ - UintXX Gmask = image->green_mask;\ - UintXX Bmask = image->blue_mask;\ - UintXX Amask = 0;\ - Uint32 wx, wy;\ - Uint32 p1, p2, p3, p4;\ -\ - /* - * Interpolation: - * We calculate the distances from our point to the four nearest pixels, d1..d4. - * d(a,b) = sqrt(a�+b�) ~= 0.707(a+b) (Pythagoras (Taylor) expanded around (0.5;0.5)) - * - * 1 wx 2 - * *-|-* (+ = our point at (x,y)) - * | | | (* = the four nearest pixels) - * wy --+ | wx = float(x) - int(x) - * | | wy = float(y) - int(y) - * *---* - * 3 4 - * d1 = d(wx,wy) d2 = d(1-wx,wy) d3 = d(wx,1-wy) d4 = d(1-wx,1-wy) - * We now want to weight each pixels importance - it's vicinity to our point: - * w1=d4 w2=d3 w3=d2 w4=d1 (Yes it works... just think a bit about it) - * - * If the pixels have the colors c1..c4 then our point should have the color - * c = (w1*c1 + w2*c2 + w3*c3 + w4*c4)/(w1+w2+w3+w4) (the weighted average) - * but w1+w2+w3+w4 = 4*0.707 so we might as well write it as - * c = p1*c1 + p2*c2 + p3*c3 + p4*c4 where p1..p4 = (w1..w4)/(4*0.707) - * - * But p1..p4 are fixed point so we can just divide the fixed point constant! - * 8192/(4*0.71) = 2897 and we can skip 0.71 too (the division will cancel it everywhere) - * 8192/4 = 2048 - * - * 020102: I changed the fixed-point representation for the variables in the weighted average - * to 24.7 to avoid problems with 32bit colors. Everything else is still 18.13. This - * does however not solve the problem with 32bit RGBA colors... - */\ -\ - Sint32 one = 2048>>6; /* 1 in Fixed-point */ \ - Sint32 two = 2*2048>>6; /* 2 in Fixed-point */ \ -\ - for (y=ymin; y<ymax; y++){ \ - dy = y - qy; \ -\ - sx = (Sint32)(ctdx); /* Compute source anchor points */ \ - sy = (Sint32)(cty*dy); \ -\ - /* Calculate pointer to dst surface */ \ - dst_row = (UintXX *)dst->pixels + y*dst_pitch; \ -\ - for (x=xmin; x<xmax; x++){ \ - rx=(Sint16)(sx >> 13); /* Convert from fixed-point */ \ - ry=(Sint16)(sy >> 13); \ -\ - /* Make sure the source pixel is actually in the source image. */ \ - if( (rx>=sxmin) && (rx+1<sxmax) && (ry>=symin) && (ry+1<symax) ){ \ - wx = (sx & 0x00001FFF) >>8; /* (float(x) - int(x)) / 4 */ \ - wy = (sy & 0x00001FFF) >>8;\ -\ - p4 = wx+wy;\ - p3 = one-wx+wy;\ - p2 = wx+one-wy;\ - p1 = two-wx-wy;\ -\ - c1 = *(src_row + ry*src_pitch + rx);\ - c2 = *(src_row + ry*src_pitch + rx+1);\ - c3 = *(src_row + (ry+1)*src_pitch + rx);\ - c4 = *(src_row + (ry+1)*src_pitch + rx+1);\ -\ - /* Calculate the average */\ - R = ((p1*(c1 & Rmask) + p2*(c2 & Rmask) + p3*(c3 & Rmask) + p4*(c4 & Rmask))>>7) & Rmask;\ - G = ((p1*(c1 & Gmask) + p2*(c2 & Gmask) + p3*(c3 & Gmask) + p4*(c4 & Gmask))>>7) & Gmask;\ - B = ((p1*(c1 & Bmask) + p2*(c2 & Bmask) + p3*(c3 & Bmask) + p4*(c4 & Bmask))>>7) & Bmask;\ - if(Amask)\ - A = ((p1*(c1 & Amask) + p2*(c2 & Amask) + p3*(c3 & Amask) + p4*(c4 & Amask))>>7) & Amask;\ - \ - *(dst_row + x) = R | G | B | A;\ - } \ - sx += ctx; /* Incremental transformations */ \ - } \ - } - -void sge_transform(Surface *src, Surface *dst, float xscale, float yscale, Uint16 qx, Uint16 qy) -{ - Sint32 dy, sx, sy; - Sint16 x, y, rx, ry; - Rect r; - - Sint32 ctx, cty; - Sint16 xmin, xmax, ymin, ymax; - Sint16 sxmin, sxmax, symin, symax; - Sint32 dx, ctdx; - - - /* Here we use 18.13 fixed point integer math - // Sint32 should have 31 usable bits and one for sign - // 2^13 = 8192 - */ - - /* Check scales */ - Sint32 maxint = (Sint32)(pow(2, sizeof(Sint32)*8 - 1 - 13)); /* 2^(31-13) */ - - r.x = r.y = r.w = r.h = 0; - - if( xscale == 0 || yscale == 0) - return; - - if( 8192.0/xscale > maxint ) - xscale = (float)(8192.0/maxint); - else if( 8192.0/xscale < -maxint ) - xscale = (float)(-8192.0/maxint); - - if( 8192.0/yscale > maxint ) - yscale = (float)(8192.0/maxint); - else if( 8192.0/yscale < -maxint ) - yscale = (float)(-8192.0/maxint); - - - /* Fixed-point equivalents */ - ctx = (Sint32)(8192.0/xscale); - cty = (Sint32)(8192.0/yscale); - - /* Compute a bounding rectangle */ - xmin=0; xmax=dst->w; ymin=0; ymax=dst->h; - _calcRect(src, dst, xscale, yscale, - qx, qy, &xmin, &ymin, &xmax, &ymax); - - /* Clip to src surface */ - sxmin = sge_clip_xmin(src); - sxmax = sge_clip_xmax(src); - symin = sge_clip_ymin(src); - symax = sge_clip_ymax(src); - - /* Some terms in the transform are constant */ - dx = xmin - qx; - ctdx = ctx*dx; - - /* Use the correct bpp */ - if( src->BytesPerPixel == dst->BytesPerPixel){ - switch( src->BytesPerPixel ){ - case 1: { /* Assuming 8-bpp */ - TRANSFORM(Uint8, 1) - } - break; - case 2: { /* Probably 15-bpp or 16-bpp */ - TRANSFORM_AA(Uint16, 2) - } - break; - case 4: { /* Probably 32-bpp */ - TRANSFORM_AA(Uint32, 4) - } - break; - } - } -} - -void freeDesktopResources() { - Cleanup(); - if (image) { - XDestroyImage(image); - } - if (zoomImage) { - XDestroyImage(zoomImage); - } - if (savedArea) - free(savedArea); - - if (gcInited) { - XFreeGC(dpy, gc); - XFreeGC(dpy, srcGC); - XFreeGC(dpy, dstGC); - } - - caughtShmError = False; - needShmCleanup = False; - caughtZoomShmError = False; - needZoomShmCleanup = False; - gcInited = False; - image = NULL; - useShm = True; - zoomActive = False; - zoomImage = NULL; - useZoomShm = True; - savedArea = NULL; -} - - -/* - * ColorRectangle32 - * Only used for debugging / visualizing output - */ -/* -static void -ColorRectangle32(XImage *img, CARD32 fg, int x, int y, int width, int height) -{ - int i, h; - int scrWidthInBytes = img->bytes_per_line; - char *scr; - CARD32 *scr32; - - if ((!img) || (!img->data)) - return; - - scr = (img->data + y * scrWidthInBytes + x * 4); - - if (!CheckRectangle(x, y, width, height)) - return; - - for (h = 0; h < height; h++) { - scr32 = (CARD32*) scr; - for (i = 0; i < width; i++) { - CARD32 n = 0; - CARD32 p = scr32[i]; - if (0xff & fg) - n |= ((( 0xff & p)+( 0xff & fg)) >> 2) & 0xff; - else - n |= (0xff & p); - if (0xff00 & fg) - n |= ((( 0xff00 & p)+( 0xff00 & fg)) >> 2) & 0xff00; - else - n |= (0xff00 & p); - if (0xff0000 & fg) - n |= (((0xff0000 & p)+(0xff0000 & fg)) >> 2) & 0xff0000; - else - n |= (0xff0000 & p); - scr32[i] = n; - } - scr += scrWidthInBytes; - } -} -*/ - diff --git a/krdc/vnc/hextile.c b/krdc/vnc/hextile.c deleted file mode 100644 index 207d93c8..00000000 --- a/krdc/vnc/hextile.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -/* - * hextile.c - handle hextile encoding. - * - * This file shouldn't be compiled directly. It is included multiple times by - * rfbproto.c, each time with a different definition of the macro BPP. For - * each value of BPP, this file defines a function which handles a hextile - * encoded rectangle with BPP bits per pixel. - */ - -#define HandleHextileBPP CONCAT2E(HandleHextile,BPP) -#define CARDBPP CONCAT2E(CARD,BPP) -#define GET_PIXEL CONCAT2E(GET_PIXEL,BPP) -#define FillRectangleBPP CONCAT2E(FillRectangle,BPP) - -static Bool -HandleHextileBPP (int rx, int ry, int rw, int rh) -{ - CARDBPP bg, fg; - int i; - CARD8 *ptr; - int x, y, w, h; - int sx, sy, sw, sh; - CARD8 subencoding; - CARD8 nSubrects; - - for (y = ry; y < ry+rh; y += 16) { - for (x = rx; x < rx+rw; x += 16) { - w = h = 16; - if (rx+rw - x < 16) - w = rx+rw - x; - if (ry+rh - y < 16) - h = ry+rh - y; - - if (!ReadFromRFBServer((char *)&subencoding, 1)) - return False; - - if (subencoding & rfbHextileRaw) { - if (!ReadFromRFBServer(buffer, w * h * (BPP / 8))) - return False; - - CopyDataToScreen(buffer, x, y, w, h); - continue; - } - - if (subencoding & rfbHextileBackgroundSpecified) - if (!ReadFromRFBServer((char *)&bg, sizeof(bg))) - return False; - - LockFramebuffer(); - FillRectangleBPP(bg, x, y, w, h); - - if (subencoding & rfbHextileForegroundSpecified) - if (!ReadFromRFBServer((char *)&fg, sizeof(fg))) { - UnlockFramebuffer(); - return False; - } - - if (!(subencoding & rfbHextileAnySubrects)) { - UnlockFramebuffer(); - SyncScreenRegion(x, y, w, h); - continue; - } - - if (!ReadFromRFBServer((char *)&nSubrects, 1)) { - UnlockFramebuffer(); - return False; - } - - ptr = (CARD8 *)buffer; - - if (subencoding & rfbHextileSubrectsColoured) { - if (!ReadFromRFBServer(buffer, nSubrects * (2 + (BPP / 8)))) { - UnlockFramebuffer(); - return False; - } - - for (i = 0; i < nSubrects; i++) { - GET_PIXEL(fg, ptr); - sx = rfbHextileExtractX(*ptr); - sy = rfbHextileExtractY(*ptr); - ptr++; - sw = rfbHextileExtractW(*ptr); - sh = rfbHextileExtractH(*ptr); - ptr++; - FillRectangleBPP(fg, x+sx, y+sy, sw, sh); - } - - } else { - if (!ReadFromRFBServer(buffer, nSubrects * 2)) { - UnlockFramebuffer(); - return False; - } - - for (i = 0; i < nSubrects; i++) { - sx = rfbHextileExtractX(*ptr); - sy = rfbHextileExtractY(*ptr); - ptr++; - sw = rfbHextileExtractW(*ptr); - sh = rfbHextileExtractH(*ptr); - ptr++; - FillRectangleBPP(fg, x+sx, y+sy, sw, sh); - } - } - UnlockFramebuffer(); - SyncScreenRegion(x, y, w, h); - } - } - - return True; -} diff --git a/krdc/vnc/kvncview.cpp b/krdc/vnc/kvncview.cpp index 22960423..b7ca3685 100644 --- a/krdc/vnc/kvncview.cpp +++ b/krdc/vnc/kvncview.cpp @@ -2,7 +2,8 @@ kvncview.cpp - main widget ------------------- begin : Thu Dec 20 15:11:42 CET 2001 - copyright : (C) 2001-2003 by Tim Jansen + copyright : (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net> + (C) 2001-2003 by Tim Jansen email : tim@tjansen.de ***************************************************************************/ @@ -34,6 +35,8 @@ #include <tqbitmap.h> #include <tqmutex.h> #include <tqvbox.h> +#include <tqtimer.h> +#include <tqpainter.h> #include <tqwaitcondition.h> #include "vncviewer.h" @@ -47,7 +50,6 @@ bool launch_Fullscreen_vnc = false; * application resource specs. The AppData structure is defined in the header * file. */ -AppData appData; bool appDataConfigured = false; Display* dpy; @@ -73,8 +75,7 @@ KVncView::KVncView(TQWidget *parent, DotCursorState dotCursorState, const TQString &encodings) : KRemoteView(parent, name, TQt::WResizeNoErase | TQt::WRepaintNoErase | TQt::WStaticContents), - m_cthread(this, m_wthread, m_quitFlag), - m_wthread(this, m_quitFlag), + m_cthreadObject(this, m_quitFlag), m_quitFlag(false), m_enableFramebufferLocking(false), m_scaling(false), @@ -147,8 +148,6 @@ int KVncView::port() { void KVncView::startQuitting() { m_quitFlag = true; - m_wthread.kick(); - m_cthread.kick(); } bool KVncView::isQuitting() { @@ -157,44 +156,37 @@ bool KVncView::isQuitting() { void KVncView::configureApp(Quality q, const TQString specialEncodings) { appDataConfigured = true; - appData.shareDesktop = 1; - appData.viewOnly = 0; + m_cthreadObject.cl->appData.shareDesktop = 1; + m_cthreadObject.cl->appData.viewOnly = 0; if (q == QUALITY_LOW) { - appData.useBGR233 = 1; - appData.encodingsString = "background copyrect softcursor tight zlib hextile raw"; - appData.compressLevel = -1; - appData.qualityLevel = 1; - appData.dotCursor = 1; + m_cthreadObject.cl->appData.useBGR233 = 1; + m_cthreadObject.cl->appData.encodingsString = "tight zrle ultra copyrect hextile zlib corre rre raw"; + m_cthreadObject.cl->appData.compressLevel = 9; + m_cthreadObject.cl->appData.qualityLevel = 1; + m_cthreadObject.cl->appData.useRemoteCursor = 1; } else if (q == QUALITY_MEDIUM) { - appData.useBGR233 = 0; - appData.encodingsString = "background copyrect softcursor tight zlib hextile raw"; - appData.compressLevel = -1; - appData.qualityLevel = 7; - appData.dotCursor = 1; + m_cthreadObject.cl->appData.useBGR233 = 0; + m_cthreadObject.cl->appData.encodingsString = "tight zrle ultra copyrect hextile zlib corre rre raw"; + m_cthreadObject.cl->appData.compressLevel = 5; + m_cthreadObject.cl->appData.qualityLevel = 7; + m_cthreadObject.cl->appData.useRemoteCursor = 1; } else if ((q == QUALITY_HIGH) || (q == QUALITY_UNKNOWN)) { - appData.useBGR233 = 0; - appData.encodingsString = "copyrect softcursor hextile raw"; - appData.compressLevel = -1; - appData.qualityLevel = 9; - appData.dotCursor = 1; + m_cthreadObject.cl->appData.useBGR233 = 0; + m_cthreadObject.cl->appData.encodingsString = "copyrect hextile raw"; + m_cthreadObject.cl->appData.compressLevel = 0; + m_cthreadObject.cl->appData.qualityLevel = 9; + m_cthreadObject.cl->appData.useRemoteCursor = 1; } - if (!specialEncodings.isNull()) - appData.encodingsString = specialEncodings.latin1(); - - appData.nColours = 256; - appData.useSharedColours = 1; - appData.requestedDepth = 0; - - appData.rawDelay = 0; - appData.copyRectDelay = 0; + if (!specialEncodings.isNull()) { + m_cthreadObject.cl->appData.encodingsString = specialEncodings.latin1(); + } - if (!appData.dotCursor) - m_cursorState = DOT_CURSOR_OFF; - showDotCursorInternal(); + m_cthreadObject.cl->appData.nColours = 256; + m_cthreadObject.cl->appData.requestedDepth = 0; } bool KVncView::checkLocalKRfb() { @@ -297,7 +289,10 @@ bool KVncView::start() { setStatus(REMOTE_VIEW_CONNECTING); + m_cthreadObject.moveToThread(&m_cthread); + TQTimer::singleShot(0, &m_cthreadObject, SLOT(run())); m_cthread.start(); + setBackgroundMode(TQt::NoBackground); return true; } @@ -306,8 +301,6 @@ KVncView::~KVncView() { startQuitting(); m_cthread.wait(); - m_wthread.wait(); - freeResources(); } bool KVncView::supportsLocalCursor() const { @@ -354,9 +347,16 @@ void KVncView::enableScaling(bool s) { setMaximumSize(m_framebufferSize); setMinimumSize(m_framebufferSize.width()/16, m_framebufferSize.height()/16); + + m_cthreadObject.setScaling(width(), height()); } - else + else { setFixedSize(m_framebufferSize); + m_cthreadObject.setScaling(-1, -1); + } + + // Force full redraw + drawRegion(0, 0, width(), height()); } } @@ -367,12 +367,18 @@ void KVncView::paintEvent(TQPaintEvent *e) { e->rect().height()); } +void KVncView::resizeEvent(TQResizeEvent *e) { + if (m_scaling) { + m_cthreadObject.setScaling(width(), height()); + + // Force full redraw + drawRegion(0, 0, width(), height()); + } +} + void KVncView::drawRegion(int x, int y, int w, int h) { - if (m_scaling) - DrawZoomedScreenRegionX11Thread(winId(), width(), height(), - x, y, w, h); - else - DrawScreenRegionX11Thread(winId(), x, y, w, h); + TQPainter painter(this); + painter.drawImage(TQRect(x, y, w, h), m_cthreadObject.image(x, y, w, h)); } void KVncView::customEvent(TQCustomEvent *e) @@ -387,9 +393,6 @@ void KVncView::customEvent(TQCustomEvent *e) setFixedSize(m_framebufferSize); emit changeSize(sre->width(), sre->height()); } - else if (e->type() == DesktopInitEventType) { - m_cthread.desktopInit(); - } else if (e->type() == StatusChangeEventType) { StatusChangeEvent *sce = (StatusChangeEvent*) e; setStatus(sce->status()); @@ -562,10 +565,13 @@ void KVncView::mouseEvent(TQMouseEvent *e) { x = (x * m_framebufferSize.width()) / width(); y = (y * m_framebufferSize.height()) / height(); } - m_wthread.queueMouseEvent(x, y, m_buttonMask); + m_cthreadObject.queueMouseEvent(x, y, m_buttonMask); - if (m_enableClientCursor) - DrawCursorX11Thread(x, y); // in rfbproto.c + if (m_enableClientCursor) { + // FIXME + // How to draw soft cursor? + // DrawCursorX11Thread(x, y); // in rfbproto.c + } } void KVncView::mousePressEvent(TQMouseEvent *e) { @@ -606,8 +612,8 @@ void KVncView::wheelEvent(TQWheelEvent *e) { x = (x * m_framebufferSize.width()) / width(); y = (y * m_framebufferSize.height()) / height(); } - m_wthread.queueMouseEvent(x, y, eb|m_buttonMask); - m_wthread.queueMouseEvent(x, y, m_buttonMask); + m_cthreadObject.queueMouseEvent(x, y, eb|m_buttonMask); + m_cthreadObject.queueMouseEvent(x, y, m_buttonMask); e->accept(); } @@ -620,25 +626,25 @@ void KVncView::pressKey(XEvent *xe) { KKeyNative k(xe); uint mod = k.mod(); if (mod & KKeyNative::modX(KKey::SHIFT)) - m_wthread.queueKeyEvent(XK_Shift_L, true); + m_cthreadObject.queueKeyEvent(XK_Shift_L, true); if (mod & KKeyNative::modX(KKey::CTRL)) - m_wthread.queueKeyEvent(XK_Control_L, true); + m_cthreadObject.queueKeyEvent(XK_Control_L, true); if (mod & KKeyNative::modX(KKey::ALT)) - m_wthread.queueKeyEvent(XK_Alt_L, true); + m_cthreadObject.queueKeyEvent(XK_Alt_L, true); if (mod & KKeyNative::modX(KKey::WIN)) - m_wthread.queueKeyEvent(XK_Meta_L, true); + m_cthreadObject.queueKeyEvent(XK_Meta_L, true); - m_wthread.queueKeyEvent(k.sym(), true); - m_wthread.queueKeyEvent(k.sym(), false); + m_cthreadObject.queueKeyEvent(k.sym(), true); + m_cthreadObject.queueKeyEvent(k.sym(), false); if (mod & KKeyNative::modX(KKey::WIN)) - m_wthread.queueKeyEvent(XK_Meta_L, false); + m_cthreadObject.queueKeyEvent(XK_Meta_L, false); if (mod & KKeyNative::modX(KKey::ALT)) - m_wthread.queueKeyEvent(XK_Alt_L, false); + m_cthreadObject.queueKeyEvent(XK_Alt_L, false); if (mod & KKeyNative::modX(KKey::CTRL)) - m_wthread.queueKeyEvent(XK_Control_L, false); + m_cthreadObject.queueKeyEvent(XK_Control_L, false); if (mod & KKeyNative::modX(KKey::SHIFT)) - m_wthread.queueKeyEvent(XK_Shift_L, false); + m_cthreadObject.queueKeyEvent(XK_Shift_L, false); m_mods.clear(); } @@ -671,7 +677,7 @@ bool KVncView::x11Event(XEvent *e) { else unpressModifiers(); } - m_wthread.queueKeyEvent(s, pressed); + m_cthreadObject.queueKeyEvent(s, pressed); } return true; } @@ -680,7 +686,7 @@ void KVncView::unpressModifiers() { TQValueList<unsigned int> keys = m_mods.keys(); TQValueList<unsigned int>::const_iterator it = keys.begin(); while (it != keys.end()) { - m_wthread.queueKeyEvent(*it, false); + m_cthreadObject.queueKeyEvent(*it, false); it++; } m_mods.clear(); @@ -713,7 +719,7 @@ void KVncView::clipboardChanged() { if (text.length() > MAX_SELECTION_LENGTH) return; - m_wthread.queueClientCut(text); + m_cthreadObject.queueClientCut(text); } void KVncView::selectionChanged() { @@ -727,7 +733,7 @@ void KVncView::selectionChanged() { if (text.length() > MAX_SELECTION_LENGTH) return; - m_wthread.queueClientCut(text); + m_cthreadObject.queueClientCut(text); } @@ -759,7 +765,7 @@ void KVncView::enableClientCursor(bool enable) { locks and signals are there to protect against deadlocks and other horribleness. Be careful making changes here. */ -int getPassword(char *passwd, int pwlen) { +int getPassword(char * &passwd) { int retV = 0; //Prepare the system @@ -786,9 +792,7 @@ int getPassword(char *passwd, int pwlen) { //Process the password if we got it, clear it if we didn't if (retV) { - strncpy(passwd, (const char*)password, pwlen); - } else { - passwd[0] = 0; + passwd = strdup((const char*)password); } //Pack up and go home diff --git a/krdc/vnc/kvncview.h b/krdc/vnc/kvncview.h index daaf30b1..d869846b 100644 --- a/krdc/vnc/kvncview.h +++ b/krdc/vnc/kvncview.h @@ -2,7 +2,8 @@ kvncview.h - widget that shows the vnc client ------------------- begin : Thu Dec 20 15:11:42 CET 2001 - copyright : (C) 2001-2003 by Tim Jansen + copyright : (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net> + (C) 2001-2003 by Tim Jansen email : tim@tjansen.de ***************************************************************************/ @@ -24,7 +25,6 @@ #include "pointerlatencyometer.h" #include "hostpreferences.h" -#include "vnctypes.h" #include "threads.h" class TQClipBoard; @@ -34,8 +34,8 @@ class KVncView : public KRemoteView Q_OBJECT private: - ControllerThread m_cthread; - WriterThread m_wthread; + ControllerThreadObject m_cthreadObject; + TQEventLoopThread m_cthread; volatile bool m_quitFlag; // if set: all threads should die ASAP TQMutex m_framebufferLock; bool m_enableFramebufferLocking; @@ -74,6 +74,7 @@ protected: void mouseMoveEvent(TQMouseEvent*); void wheelEvent(TQWheelEvent *); void focusOutEvent(TQFocusEvent *); + void resizeEvent(TQResizeEvent *); bool x11Event(XEvent*); public: @@ -116,6 +117,8 @@ public slots: private slots: +// void requestPassword(); + void clipboardChanged(); void selectionChanged(); }; diff --git a/krdc/vnc/rfbproto.c b/krdc/vnc/rfbproto.c deleted file mode 100644 index 8424e6ac..00000000 --- a/krdc/vnc/rfbproto.c +++ /dev/null @@ -1,1335 +0,0 @@ -/* - * Copyright (C) 2002, Tim Jansen. All Rights Reserved. - * Copyright (C) 2000-2002 Constantin Kaplinsky. All Rights Reserved. - * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. - * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -/* - * rfbproto.c - functions to deal with client side of RFB protocol. - * tim@tjansen.de: - added softcursor encoding - * - changed various things for krdc - */ - -#include <unistd.h> -#include <errno.h> -#include <pwd.h> -#include "vncviewer.h" -#include "vncauth.h" -#include <zlib.h> -#include <jpeglib.h> - -static Bool HandleHextile8(int rx, int ry, int rw, int rh); -static Bool HandleHextile16(int rx, int ry, int rw, int rh); -static Bool HandleHextile32(int rx, int ry, int rw, int rh); -static Bool HandleZlib8(int rx, int ry, int rw, int rh); -static Bool HandleZlib16(int rx, int ry, int rw, int rh); -static Bool HandleZlib32(int rx, int ry, int rw, int rh); -static Bool HandleTight8(int rx, int ry, int rw, int rh); -static Bool HandleTight16(int rx, int ry, int rw, int rh); -static Bool HandleTight32(int rx, int ry, int rw, int rh); - -static long ReadCompactLen (void); - -static void JpegInitSource(j_decompress_ptr cinfo); -static boolean JpegFillInputBuffer(j_decompress_ptr cinfo); -static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes); -static void JpegTermSource(j_decompress_ptr cinfo); -static void JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData, - int compressedLen); - - -#define RGB24_TO_PIXEL(bpp,r,g,b) \ - ((((CARD##bpp)(r) & 0xFF) * myFormat.redMax + 127) / 255 \ - << myFormat.redShift | \ - (((CARD##bpp)(g) & 0xFF) * myFormat.greenMax + 127) / 255 \ - << myFormat.greenShift | \ - (((CARD##bpp)(b) & 0xFF) * myFormat.blueMax + 127) / 255 \ - << myFormat.blueShift) - -int rfbsock; -char *desktopName; -rfbPixelFormat myFormat; -rfbServerInitMsg si; - -int endianTest = 1; - -/* - * Softcursor variables - */ - -int cursorX, cursorY; -int imageIndex = -1; - -PointerImage pointerImages[rfbSoftCursorMaxImages]; - - -/* Hextile assumes it is big enough to hold 16 * 16 * 32 bits. - Tight encoding assumes BUFFER_SIZE is at least 16384 bytes. */ - -#define BUFFER_SIZE (16384) -static char buffer[BUFFER_SIZE]; - - -/* The zlib encoding requires expansion/decompression/deflation of the - compressed data in the "buffer" above into another, result buffer. - However, the size of the result buffer can be determined precisely - based on the bitsPerPixel, height and width of the rectangle. We - allocate this buffer one time to be the full size of the buffer. */ - -static int raw_buffer_size = -1; -static char *raw_buffer = NULL; - -static z_stream decompStream; -static Bool decompStreamInited = False; - - -/* - * Variables for the ``tight'' encoding implementation. - */ - -/* Separate buffer for compressed data. */ -#define ZLIB_BUFFER_SIZE 512 -static char zlib_buffer[ZLIB_BUFFER_SIZE]; - -/* Four independent compression streams for zlib library. */ -static z_stream zlibStream[4]; -static Bool zlibStreamActive[4] = { - False, False, False, False -}; - -/* Filter stuff. Should be initialized by filter initialization code. */ -static Bool cutZeros; -static int rectWidth, rectColors; -static char tightPalette[256*4]; -static CARD8 tightPrevRow[2048*3*sizeof(CARD16)]; - -/* JPEG decoder state. */ -static Bool jpegError; - -/* Maximum length for the cut buffer (16 MB)*/ -#define MAX_CUTBUFFER (1024*1024*16) - -/* Maximum length for the strings (64 kB)*/ -#define MAX_STRING (1024*64) - -/* Maximum length for the strings (32 MB)*/ -#define MAX_JPEG_SIZE (1024*1024*32) - - -/* - * ConnectToRFBServer. - */ - -int -ConnectToRFBServer(const char *hostname, int port) -{ - unsigned int host; - - if (!StringToIPAddr(hostname, &host)) { - fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname); - return -(int)INIT_NAME_RESOLUTION_FAILURE; - } - - rfbsock = ConnectToTcpAddr(host, port); - if (rfbsock < 0) { - fprintf(stderr,"Unable to connect to VNC server\n"); - } - - return rfbsock; -} - - -/* - * InitialiseRFBConnection. - */ - -enum InitStatus -InitialiseRFBConnection() -{ - rfbProtocolVersionMsg pv; - int major,minor; - CARD32 authScheme, reasonLen, authResult; - char *reason; - CARD8 challenge[CHALLENGESIZE]; - char passwd[9]; - int i; - rfbClientInitMsg ci; - - /* if the connection is immediately closed, don't report anything, so - that pmw's monitor can make test connections */ - - if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg)) return INIT_SERVER_BLOCKED; - - errorMessageOnReadFailure = True; - - pv[sz_rfbProtocolVersionMsg] = 0; - - if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) { - fprintf(stderr,"Not a valid VNC server\n"); - return INIT_PROTOCOL_FAILURE; - } - - fprintf(stderr,"VNC server supports protocol version %d.%d (viewer %d.%d)\n", - major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion); - - major = rfbProtocolMajorVersion; - minor = rfbProtocolMinorVersion; - - sprintf(pv,rfbProtocolVersionFormat,major,minor); - - if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) return INIT_CONNECTION_FAILED; - - if (!ReadFromRFBServer((char *)&authScheme, 4)) return INIT_CONNECTION_FAILED; - - authScheme = Swap32IfLE(authScheme); - - switch (authScheme) { - - case rfbConnFailed: - if (!ReadFromRFBServer((char *)&reasonLen, 4)) return INIT_CONNECTION_FAILED; - reasonLen = Swap32IfLE(reasonLen); - - if (reasonLen > MAX_STRING) { - fprintf(stderr, "Connection failure reason too long.\n"); - return INIT_CONNECTION_FAILED; - } - - reason = malloc(reasonLen); - if (!reason) - return INIT_CONNECTION_FAILED; - - if (!ReadFromRFBServer(reason, reasonLen)) return INIT_CONNECTION_FAILED; - - fprintf(stderr,"VNC connection failed: %.*s\n",(int)reasonLen, reason); - free(reason); - return INIT_CONNECTION_FAILED; - - case rfbNoAuth: - fprintf(stderr,"No authentication needed\n"); - break; - - case rfbVncAuth: - if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE)) return INIT_CONNECTION_FAILED; - - if (!getPassword(passwd, 8)) - return INIT_ABORTED; - - passwd[8] = '\0'; - - vncEncryptBytes(challenge, passwd); - - /* Lose the password from memory */ - for (i = strlen(passwd); i >= 0; i--) { - passwd[i] = '\0'; - } - - if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE)) return INIT_CONNECTION_FAILED; - - if (!ReadFromRFBServer((char *)&authResult, 4)) return INIT_CONNECTION_FAILED; - - authResult = Swap32IfLE(authResult); - - switch (authResult) { - case rfbVncAuthOK: - fprintf(stderr,"VNC authentication succeeded\n"); - break; - case rfbVncAuthFailed: - fprintf(stderr,"VNC authentication failed\n"); - return INIT_AUTHENTICATION_FAILED; - case rfbVncAuthTooMany: - fprintf(stderr,"VNC authentication failed - too many tries\n"); - return INIT_AUTHENTICATION_FAILED; - default: - fprintf(stderr,"Unknown VNC authentication result: %d\n", - (int)authResult); - return INIT_CONNECTION_FAILED; - } - break; - - default: - fprintf(stderr,"Unknown authentication scheme from VNC server: %d\n", - (int)authScheme); - return INIT_CONNECTION_FAILED; - } - - ci.shared = (appData.shareDesktop ? 1 : 0); - - if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) return INIT_CONNECTION_FAILED; - - if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) return INIT_CONNECTION_FAILED; - - si.framebufferWidth = Swap16IfLE(si.framebufferWidth); - si.framebufferHeight = Swap16IfLE(si.framebufferHeight); - si.format.redMax = Swap16IfLE(si.format.redMax); - si.format.greenMax = Swap16IfLE(si.format.greenMax); - si.format.blueMax = Swap16IfLE(si.format.blueMax); - si.nameLength = Swap32IfLE(si.nameLength); - - if ((si.framebufferWidth*si.framebufferHeight) > (4096*4096)) - return INIT_CONNECTION_FAILED; - - if (si.nameLength > MAX_STRING) { - fprintf(stderr, "Display name too long.\n"); - return INIT_CONNECTION_FAILED; - } - - desktopName = malloc(si.nameLength + 1); - if (!desktopName) { - fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n", - (unsigned long)si.nameLength); - return INIT_CONNECTION_FAILED; - } - - if (!ReadFromRFBServer(desktopName, si.nameLength)) return INIT_CONNECTION_FAILED; - - desktopName[si.nameLength] = 0; - - fprintf(stderr,"Desktop name \"%s\"\n",desktopName); - - fprintf(stderr,"Connected to VNC server, using protocol version %d.%d\n", - rfbProtocolMajorVersion, rfbProtocolMinorVersion); - - fprintf(stderr,"VNC server default format:\n"); - PrintPixelFormat(&si.format); - - return INIT_OK; -} - - -/* - * SetFormatAndEncodings. - */ - -Bool -SetFormatAndEncodings() -{ - rfbSetPixelFormatMsg spf; - char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4]; - rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf; - CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]); - int len = 0; - Bool requestCompressLevel = False; - Bool requestQualityLevel = False; - Bool requestLastRectEncoding = False; - - spf.type = rfbSetPixelFormat; - spf.pad1 = 0; - spf.pad2 = 0; - spf.format = myFormat; - spf.format.redMax = Swap16IfLE(spf.format.redMax); - spf.format.greenMax = Swap16IfLE(spf.format.greenMax); - spf.format.blueMax = Swap16IfLE(spf.format.blueMax); - - if (!WriteExact(rfbsock, (char *)&spf, sz_rfbSetPixelFormatMsg)) - return False; - - se->type = rfbSetEncodings; - se->pad = 0; - se->nEncodings = 0; - - if (appData.encodingsString) { - const char *encStr = appData.encodingsString; - int encStrLen; - do { - char *nextEncStr = strchr(encStr, ' '); - if (nextEncStr) { - encStrLen = nextEncStr - encStr; - nextEncStr++; - } else { - encStrLen = strlen(encStr); - } - - if (strncasecmp(encStr,"raw",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw); - } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect); - } else if (strncasecmp(encStr,"softcursor",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingSoftCursor); - /* if server supports SoftCursor, it will ignore X/RichCursor - * and PointerPos */ - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor); - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor); - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos); - } else if (strncasecmp(encStr,"background",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingBackground); - } else if (strncasecmp(encStr,"tight",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight); - requestLastRectEncoding = True; - if (appData.compressLevel >= 0 && appData.compressLevel <= 9) - requestCompressLevel = True; - if (appData.qualityLevel >= 0 && appData.qualityLevel <= 9) - requestQualityLevel = True; - } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile); - } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib); - if (appData.compressLevel >= 0 && appData.compressLevel <= 9) - requestCompressLevel = True; - } else { - fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr); - } - - encStr = nextEncStr; - } while (encStr && se->nEncodings < MAX_ENCODINGS); - - if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) { - encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + - rfbEncodingCompressLevel0); - } - - if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) { - encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + - rfbEncodingQualityLevel0); - } - - if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect); - } - } - else { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect); - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight); - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile); - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib); - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw); - - if (appData.compressLevel >= 0 && appData.compressLevel <= 9) { - encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + - rfbEncodingCompressLevel0); - } - - if (appData.qualityLevel >= 0 && appData.qualityLevel <= 9) { - encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + - rfbEncodingQualityLevel0); - } - - if (si.format.depth >= 8) - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingSoftCursor); - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect); - } - - len = sz_rfbSetEncodingsMsg + se->nEncodings * 4; - - se->nEncodings = Swap16IfLE(se->nEncodings); - - if (!WriteExact(rfbsock, buf, len)) return False; - - return True; -} - - -/* - * SendIncrementalFramebufferUpdateRequest. - * Note: this should only be called by the WriterThread - */ - -Bool -SendIncrementalFramebufferUpdateRequest() -{ - return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, - si.framebufferHeight, True); -} - - -/* - * SendFramebufferUpdateRequest. - * Note: this should only be called by the WriterThread - */ - -Bool -SendFramebufferUpdateRequest(int x, int y, int w, int h, Bool incremental) -{ - rfbFramebufferUpdateRequestMsg fur; - - fur.type = rfbFramebufferUpdateRequest; - fur.incremental = incremental ? 1 : 0; - fur.x = Swap16IfLE(x); - fur.y = Swap16IfLE(y); - fur.w = Swap16IfLE(w); - fur.h = Swap16IfLE(h); - - if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg)) - return False; - - return True; -} - - -/* - * SendPointerEvent. - * Note: this should only be called by the WriterThread - */ - -Bool -SendPointerEvent(int x, int y, int buttonMask) -{ - rfbPointerEventMsg pe; - - pe.type = rfbPointerEvent; - pe.buttonMask = buttonMask; - if (x < 0) x = 0; - if (y < 0) y = 0; - pe.x = Swap16IfLE(x); - pe.y = Swap16IfLE(y); - return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg); -} - - -/* - * SendKeyEvent. - * Note: this should only be called by the WriterThread - */ - -Bool -SendKeyEvent(CARD32 key, Bool down) -{ - rfbKeyEventMsg ke; - - ke.type = rfbKeyEvent; - ke.down = down ? 1 : 0; - ke.key = Swap32IfLE(key); - return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg); -} - - -/* - * SendClientCutText. - * Note: this should only be called by the WriterThread - */ - -Bool -SendClientCutText(const char *str, int len) -{ - rfbClientCutTextMsg cct; - - cct.type = rfbClientCutText; - cct.length = Swap32IfLE((unsigned int)len); - return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) && - WriteExact(rfbsock, str, len)); -} - - -static Bool -HandleSoftCursorSetImage(rfbSoftCursorSetImage *msg, rfbRectangle *rect) -{ - int iindex = msg->imageIndex - rfbSoftCursorSetIconOffset; - PointerImage *pi = &pointerImages[iindex]; - if (iindex >= rfbSoftCursorMaxImages) { - fprintf(stderr, "Received invalid soft cursor image index %d for SetImage\n", iindex); - return False; - } - EnableClientCursor(0); - - if (pi->set && pi->image) - free(pi->image); - - pi->w = rect->w; - pi->h = rect->h; - pi->hotX = rect->x; - pi->hotY = rect->y; - pi->len = Swap16IfLE(msg->imageLength); - pi->image = malloc(pi->len); - if (!pi->image) { - fprintf(stderr, "out of memory (size=%d)\n", pi->len); - return False; - } - - if (!ReadFromRFBServer(pi->image, pi->len)) - return False; - pi->set = 1; - return True; -} - -/* framebuffer must be locked when calling this!!! */ -static Bool -PointerMove(unsigned int x, unsigned int y, unsigned int mask, - int ox, int oy, int ow, int oh) -{ - int nx, ny, nw, nh; - - if (x >= si.framebufferWidth) - x = si.framebufferWidth - 1; - if (y >= si.framebufferHeight) - y = si.framebufferHeight - 1; - - cursorX = x; - cursorY = y; - drawCursor(); - UnlockFramebuffer(); - - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &nx, &ny, &nw, &nh); - - if (rectsIntersect(ox, oy, ow, oh, nx, ny, nw, nh)) { - rectsJoin(&ox, &oy, &ow, &oh, nx, ny, nw, nh); - SyncScreenRegion(ox, oy, ow, oh); - } - else { - SyncScreenRegion(ox, oy, ow, oh); - SyncScreenRegion(nx, ny, nw, nh); - } - - postMouseEvent(cursorX, cursorY, mask); - - return True; -} - -static Bool -HandleSoftCursorMove(rfbSoftCursorMove *msg, rfbRectangle *rect) -{ - int ii, ox, oy, ow, oh; - - /* get old cursor rect to know what to update */ - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &ox, &oy, &ow, &oh); - - ii = msg->imageIndex; - if (ii >= rfbSoftCursorMaxImages) { - fprintf(stderr, "Received invalid soft cursor image index %d for Move\n", ii); - return False; - } - - if (!pointerImages[ii].set) - return True; - - LockFramebuffer(); - undrawCursor(); - imageIndex = ii; - - return PointerMove(rect->w, rect->h, msg->buttonMask, ox, oy, ow, oh); -} - -static Bool -HandleCursorPos(unsigned int x, unsigned int y) -{ - int ox, oy, ow, oh; - - /* get old cursor rect to know what to update */ - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &ox, &oy, &ow, &oh); - if (!pointerImages[0].set) - return True; - - LockFramebuffer(); - undrawCursor(); - imageIndex = 0; - return PointerMove(x, y, 0, ox, oy, ow, oh); -} - -/* call only from X11 thread. Only updates framebuffer, does not sync! */ -void DrawCursorX11Thread(int x, int y) { - int ox, oy, ow, oh, nx, ny, nw, nh; - if (!pointerImages[0].set) - return True; - imageIndex = 0; - - if (x >= si.framebufferWidth) - x = si.framebufferWidth - 1; - if (y >= si.framebufferHeight) - y = si.framebufferHeight - 1; - - LockFramebuffer(); - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &ox, &oy, &ow, &oh); - undrawCursor(); - cursorX = x; - cursorY = y; - drawCursor(); - UnlockFramebuffer(); - - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &nx, &ny, &nw, &nh); - if (rectsIntersect(ox, oy, ow, oh, nx, ny, nw, nh)) { - rectsJoin(&ox, &oy, &ow, &oh, nx, ny, nw, nh); - SyncScreenRegionX11Thread(ox, oy, ow, oh); - } - else { - SyncScreenRegionX11Thread(ox, oy, ow, oh); - SyncScreenRegionX11Thread(nx, ny, nw, nh); - } -} - -/** - * Create a softcursor in the "compressed alpha" format. - * Returns the softcursor, caller owns the object - */ -static void *MakeSoftCursor(int bpp, int cursorWidth, int cursorHeight, - CARD8 *cursorData, CARD8 *cursorMask, short *imageLen) -{ - int w = (cursorWidth+7)/8; - unsigned char *cp, *sp, *dstData; - int state; /* 0 = transparent, 1 otherwise */ - CARD8 *counter; - unsigned char bit; - int i,j; - - sp = (unsigned char*)cursorData; - dstData = cp = (unsigned char*)calloc(cursorWidth*(bpp+2),cursorHeight); - if (!dstData) - return 0; - - state = 0; - counter = cp++; - *counter = 0; - - for(j=0;j<cursorHeight;j++) - for(i=0,bit=0x80;i<cursorWidth;i++,bit=(bit&1)?0x80:bit>>1) - if(cursorMask[j*w+i/8]&bit) { - if (state) { - memcpy(cp,sp,bpp); - cp += bpp; - sp += bpp; - (*counter)++; - if (*counter == 255) { - state = 0; - counter = cp++; - *counter = 0; - } - } - else { - state = 1; - counter = cp++; - *counter = 1; - memcpy(cp,sp,bpp); - cp += bpp; - sp += bpp; - } - } - else { - if (!state) { - (*counter)++; - if (*counter == 255) { - state = 1; - counter = cp++; - *counter = 0; - } - } - else { - state = 0; - counter = cp++; - *counter = 1; - } - sp += bpp; - } - - *imageLen = cp - dstData; - return (void*) dstData; -} - - -/********************************************************************* - * HandleCursorShape(). Support for XCursor and RichCursor shape - * updates. We emulate cursor operating on the frame buffer (that is - * why we call it "software cursor"). - ********************************************************************/ - -static Bool HandleCursorShape(int xhot, int yhot, int width, int height, CARD32 enc) -{ - int bytesPerPixel; - size_t bytesPerRow, bytesMaskData; - rfbXCursorColors rgb; - CARD32 colors[2]; - CARD8 *ptr, *rcSource, *rcMask; - void *softCursor; - int x, y, b; - int ox, oy, ow, oh; - PointerImage *pi; - short imageLen; - - bytesPerPixel = myFormat.bitsPerPixel / 8; - bytesPerRow = (width + 7) / 8; - bytesMaskData = bytesPerRow * height; - - if (width * height == 0) - return True; - - /* Allocate memory for pixel data and temporary mask data. */ - - rcSource = malloc(width * height * bytesPerPixel); - if (rcSource == NULL) - return False; - - rcMask = malloc(bytesMaskData); - if (rcMask == NULL) { - free(rcSource); - return False; - } - - /* Read and decode cursor pixel data, depending on the encoding type. */ - - if (enc == rfbEncodingXCursor) { - /* Read and convert background and foreground colors. */ - if (!ReadFromRFBServer((char *)&rgb, sz_rfbXCursorColors)) { - free(rcSource); - free(rcMask); - return False; - } - colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue); - colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue); - - /* Read 1bpp pixel data into a temporary buffer. */ - if (!ReadFromRFBServer((char*)rcMask, bytesMaskData)) { - free(rcSource); - free(rcMask); - return False; - } - - /* Convert 1bpp data to byte-wide color indices. */ - ptr = rcSource; - for (y = 0; y < height; y++) { - for (x = 0; x < width / 8; x++) { - for (b = 7; b >= 0; b--) { - *ptr = rcMask[y * bytesPerRow + x] >> b & 1; - ptr += bytesPerPixel; - } - } - for (b = 7; b > 7 - width % 8; b--) { - *ptr = rcMask[y * bytesPerRow + x] >> b & 1; - ptr += bytesPerPixel; - } - } - - /* Convert indices into the actual pixel values. */ - switch (bytesPerPixel) { - case 1: - for (x = 0; x < width * height; x++) - rcSource[x] = (CARD8)colors[rcSource[x]]; - break; - case 2: - for (x = 0; x < width * height; x++) - ((CARD16 *)rcSource)[x] = (CARD16)colors[rcSource[x * 2]]; - break; - case 4: - for (x = 0; x < width * height; x++) - ((CARD32 *)rcSource)[x] = colors[rcSource[x * 4]]; - break; - } - - - } else { - if (!ReadFromRFBServer((char *)rcSource, width * height * bytesPerPixel)) { - free(rcSource); - free(rcMask); - return False; - } - } - - /* Read mask data. */ - - if (!ReadFromRFBServer((char*)rcMask, bytesMaskData)) { - free(rcSource); - free(rcMask); - return False; - } - - - /* Set the soft cursor. */ - softCursor = MakeSoftCursor(bytesPerPixel, width, height, rcSource, rcMask, &imageLen); - if (!softCursor) { - free(rcMask); - free(rcSource); - return False; - } - - /* get old cursor rect to know what to update */ - EnableClientCursor(1); - LockFramebuffer(); - getBoundingRectCursor(cursorX, cursorY, imageIndex, - &ox, &oy, &ow, &oh); - undrawCursor(); - - pi = &pointerImages[0]; - if (pi->set && pi->image) - free(pi->image); - pi->w = width; - pi->h = height; - pi->hotX = xhot; - pi->hotY = yhot; - pi->len = imageLen; - pi->image = softCursor; - pi->set = 1; - - imageIndex = 0; - - free(rcMask); - free(rcSource); - - return PointerMove(cursorX, cursorY, 0, ox, oy, ow, oh); -} - - - -/* - * HandleRFBServerMessage. - */ - -Bool -HandleRFBServerMessage() -{ - rfbServerToClientMsg msg; - if (!ReadFromRFBServer((char *)&msg, 1)) - return False; - - switch (msg.type) { - - case rfbSetColourMapEntries: - { - int i; - CARD16 rgb[3]; - XColor xc; - - if (!ReadFromRFBServer(((char *)&msg) + 1, - sz_rfbSetColourMapEntriesMsg - 1)) - return False; - - msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour); - msg.scme.nColours = Swap16IfLE(msg.scme.nColours); - - for (i = 0; i < msg.scme.nColours; i++) { - if (!ReadFromRFBServer((char *)rgb, 6)) - return False; - xc.pixel = msg.scme.firstColour + i; - xc.red = Swap16IfLE(rgb[0]); - xc.green = Swap16IfLE(rgb[1]); - xc.blue = Swap16IfLE(rgb[2]); - xc.flags = DoRed|DoGreen|DoBlue; - /* Disable colormaps - lockTQt(); - XStoreColor(dpy, cmap, &xc); - unlockTQt(); - */ - } - - break; - } - - case rfbFramebufferUpdate: - { - rfbFramebufferUpdateRectHeader rect; - int linesToRead; - int bytesPerLine; - int i; - - announceIncrementalUpdateRequest(); - - if (!ReadFromRFBServer(((char *)&msg.fu) + 1, - sz_rfbFramebufferUpdateMsg - 1)) - return False; - - msg.fu.nRects = Swap16IfLE(msg.fu.nRects); - - for (i = 0; i < msg.fu.nRects; i++) { - if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader)) - return False; - - rect.encoding = Swap32IfLE(rect.encoding); - if (rect.encoding == rfbEncodingLastRect) - break; - - rect.r.x = Swap16IfLE(rect.r.x); - rect.r.y = Swap16IfLE(rect.r.y); - rect.r.w = Swap16IfLE(rect.r.w); - rect.r.h = Swap16IfLE(rect.r.h); - - if (rect.encoding == rfbEncodingPointerPos) { - if (!HandleCursorPos(rect.r.x, rect.r.y)) { - return False; - } - continue; - } - - if (rect.encoding == rfbEncodingXCursor || - rect.encoding == rfbEncodingRichCursor) { - if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, - rect.encoding)) { - return False; - } - continue; - } - - if ((rect.r.x + rect.r.w > si.framebufferWidth) || - (rect.r.y + rect.r.h > si.framebufferHeight)) - { - fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n", - rect.r.w, rect.r.h, rect.r.x, rect.r.y); - return False; - } - - if ((rect.r.h * rect.r.w == 0) && - (rect.encoding != rfbEncodingSoftCursor)) { - fprintf(stderr,"Zero size rect - ignoring\n"); - continue; - } - - switch (rect.encoding) { - - case rfbEncodingRaw: - - bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8; - linesToRead = BUFFER_SIZE / bytesPerLine; - - while (rect.r.h > 0) { - if (linesToRead > rect.r.h) - linesToRead = rect.r.h; - - if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead)) - return False; - - CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, - linesToRead); - - rect.r.h -= linesToRead; - rect.r.y += linesToRead; - - } - break; - - case rfbEncodingCopyRect: - { - rfbCopyRect cr; - - if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect)) - return False; - - cr.srcX = Swap16IfLE(cr.srcX); - cr.srcY = Swap16IfLE(cr.srcY); - - CopyArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h, rect.r.x, rect.r.y); - - break; - } - - case rfbEncodingHextile: - { - switch (myFormat.bitsPerPixel) { - case 8: - if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; - case 16: - if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; - case 32: - if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; - } - break; - } - - case rfbEncodingZlib: - { - switch (myFormat.bitsPerPixel) { - case 8: - if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; - case 16: - if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; - case 32: - if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; - } - break; - } - - case rfbEncodingTight: - { - switch (myFormat.bitsPerPixel) { - case 8: - if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; - case 16: - if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; - case 32: - if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; - } - break; - } - - case rfbEncodingSoftCursor: - { - rfbSoftCursorMsg scmsg; - if (!ReadFromRFBServer((char *)&scmsg, 1)) - return False; - if (scmsg.type < rfbSoftCursorMaxImages) { - if (!ReadFromRFBServer(((char *)&scmsg)+1, - sizeof(rfbSoftCursorMove)- 1)) - return False; - if (!HandleSoftCursorMove(&scmsg.move, &rect.r)) - return False; - } - else if((scmsg.type >= rfbSoftCursorSetIconOffset) && - (scmsg.type < rfbSoftCursorSetIconOffset+rfbSoftCursorMaxImages)) { - if (!ReadFromRFBServer(((char *)&scmsg)+1, - sizeof(rfbSoftCursorSetImage)- 1)) - return False; - if (!HandleSoftCursorSetImage(&scmsg.setImage, &rect.r)) - return False; - } - else { - fprintf(stderr,"Unknown soft cursor image index %d\n", - (int)scmsg.type); - return False; - } - break; - } - - default: - fprintf(stderr,"Unknown rect encoding %d\n", - (int)rect.encoding); - return False; - } - - } - - queueIncrementalUpdateRequest(); - - break; - } - - case rfbBell: - { - beep(); - break; - } - - case rfbServerCutText: - { - char *serverCutText; - if (!ReadFromRFBServer(((char *)&msg) + 1, - sz_rfbServerCutTextMsg - 1)) - return False; - - msg.sct.length = Swap32IfLE(msg.sct.length); - - if (msg.sct.length > MAX_CUTBUFFER) { - fprintf(stderr, "Cutbuffer too long.\n"); - return False; - } - - serverCutText = malloc(msg.sct.length+1); - - if (!serverCutText) { - fprintf(stderr, "Out-of-memory, cutbuffer too long.\n"); - return False; - } - - if (!ReadFromRFBServer(serverCutText, msg.sct.length)) - return False; - - serverCutText[msg.sct.length] = 0; - newServerCut(serverCutText, msg.sct.length); /* takes ownership of serverCutText */ - - break; - } - - default: - fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type); - return False; - } - - return True; -} - - -#define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++) - -#define GET_PIXEL16(pix, ptr) (((CARD8*)&(pix))[0] = *(ptr)++, \ - ((CARD8*)&(pix))[1] = *(ptr)++) - -#define GET_PIXEL32(pix, ptr) (((CARD8*)&(pix))[0] = *(ptr)++, \ - ((CARD8*)&(pix))[1] = *(ptr)++, \ - ((CARD8*)&(pix))[2] = *(ptr)++, \ - ((CARD8*)&(pix))[3] = *(ptr)++) - -/* CONCAT2 concatenates its two arguments. CONCAT2E does the same but also - expands its arguments if they are macros */ - -#define CONCAT2(a,b) a##b -#define CONCAT2E(a,b) CONCAT2(a,b) - -#define BPP 8 -#include "hextile.c" -#include "zlib.c" -#include "tight.c" -#undef BPP -#define BPP 16 -#include "hextile.c" -#include "zlib.c" -#include "tight.c" -#undef BPP -#define BPP 32 -#include "hextile.c" -#include "zlib.c" -#include "tight.c" -#undef BPP - - -/* - * PrintPixelFormat. - */ - -void -PrintPixelFormat(format) - rfbPixelFormat *format; -{ - if (format->bitsPerPixel == 1) { - fprintf(stderr," Single bit per pixel.\n"); - fprintf(stderr, - " %s significant bit in each byte is leftmost on the screen.\n", - (format->bigEndian ? "Most" : "Least")); - } else { - fprintf(stderr," %d bits per pixel.\n",format->bitsPerPixel); - if (format->bitsPerPixel != 8) { - fprintf(stderr," %s significant byte first in each pixel.\n", - (format->bigEndian ? "Most" : "Least")); - } - if (format->trueColour) { - fprintf(stderr," True colour: max red %d green %d blue %d", - format->redMax, format->greenMax, format->blueMax); - fprintf(stderr,", shift red %d green %d blue %d\n", - format->redShift, format->greenShift, format->blueShift); - } else { - fprintf(stderr," Colour map (not true colour).\n"); - } - } -} - -static long -ReadCompactLen (void) -{ - long len; - CARD8 b; - - if (!ReadFromRFBServer((char *)&b, 1)) - return -1; - len = (int)b & 0x7F; - if (b & 0x80) { - if (!ReadFromRFBServer((char *)&b, 1)) - return -1; - len |= ((int)b & 0x7F) << 7; - if (b & 0x80) { - if (!ReadFromRFBServer((char *)&b, 1)) - return -1; - len |= ((int)b & 0xFF) << 14; - } - } - return len; -} - -void freeRFBProtoResources() { - int i; - - if (desktopName) - free(desktopName); - if (raw_buffer) - free(raw_buffer); - for (i = 0; i < rfbSoftCursorMaxImages; i++) - if (pointerImages[i].set && pointerImages[i].image) - free(pointerImages[i].image); - - raw_buffer_size = -1; - raw_buffer = NULL; - decompStreamInited = False; - zlibStreamActive[0] = False; - zlibStreamActive[1] = False; - zlibStreamActive[2] = False; - zlibStreamActive[3] = False; - for (i = 0; i < rfbSoftCursorMaxImages; i++) - pointerImages[i].set = 0; - imageIndex = -1; -} - -void freeResources() { - freeSocketsResources(); - freeDesktopResources(); - freeRFBProtoResources(); -} - -/* - * JPEG source manager functions for JPEG decompression in Tight decoder. - */ - -static struct jpeg_source_mgr jpegSrcManager; -static JOCTET *jpegBufferPtr; -static size_t jpegBufferLen; - -static void -JpegInitSource(j_decompress_ptr cinfo) -{ - jpegError = False; -} - -static boolean -JpegFillInputBuffer(j_decompress_ptr cinfo) -{ - jpegError = True; - jpegSrcManager.bytes_in_buffer = jpegBufferLen; - jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr; - - return TRUE; -} - -static void -JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes) -{ - if (num_bytes < 0 || num_bytes > jpegSrcManager.bytes_in_buffer) { - jpegError = True; - jpegSrcManager.bytes_in_buffer = jpegBufferLen; - jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr; - } else { - jpegSrcManager.next_input_byte += (size_t) num_bytes; - jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes; - } -} - -static void -JpegTermSource(j_decompress_ptr cinfo) -{ - /* No work necessary here. */ -} - -static void -JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData, - int compressedLen) -{ - jpegBufferPtr = (JOCTET *)compressedData; - jpegBufferLen = (size_t)compressedLen; - - jpegSrcManager.init_source = JpegInitSource; - jpegSrcManager.fill_input_buffer = JpegFillInputBuffer; - jpegSrcManager.skip_input_data = JpegSkipInputData; - jpegSrcManager.resync_to_restart = jpeg_resync_to_restart; - jpegSrcManager.term_source = JpegTermSource; - jpegSrcManager.next_input_byte = jpegBufferPtr; - jpegSrcManager.bytes_in_buffer = jpegBufferLen; - - cinfo->src = &jpegSrcManager; -} - diff --git a/krdc/vnc/rfbproto.h b/krdc/vnc/rfbproto.h deleted file mode 100644 index 6cf7c740..00000000 --- a/krdc/vnc/rfbproto.h +++ /dev/null @@ -1,963 +0,0 @@ -/* - * Copyright (C) 2000-2002 Constantin Kaplinsky. All Rights Reserved. - * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. - * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -/* - * rfbproto.h - header file for the RFB protocol version 3.3 - * - * Uses types CARD<n> for an n-bit unsigned integer, INT<n> for an n-bit signed - * integer (for n = 8, 16 and 32). - * - * All multiple byte integers are in big endian (network) order (most - * significant byte first). Unless noted otherwise there is no special - * alignment of protocol structures. - * - * - * Once the initial handshaking is done, all messages start with a type byte, - * (usually) followed by message-specific data. The order of definitions in - * this file is as follows: - * - * (1) Structures used in several types of message. - * (2) Structures used in the initial handshaking. - * (3) Message types. - * (4) Encoding types. - * (5) For each message type, the form of the data following the type byte. - * Sometimes this is defined by a single structure but the more complex - * messages have to be explained by comments. - */ - -#include "vnctypes.h" - -/***************************************************************************** - * - * 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 rfbEncodingZlib 6 -#define rfbEncodingTight 7 -#define rfbEncodingZlibHex 8 - -/* - * Special encoding numbers: - * 0xFFFFFF00 .. 0xFFFFFF0F -- encoding-specific compression levels; - * 0xFFFFFF10 .. 0xFFFFFF1F -- mouse cursor shape data; - * 0xFFFFFF20 .. 0xFFFFFF2F -- various protocol extensions; - * 0xFFFFFF30 .. 0xFFFFFFDF -- not allocated yet; - * 0xFFFFFFE0 .. 0xFFFFFFEF -- quality level for JPEG compressor; - * 0xFFFFFFF0 .. 0xFFFFFFFF -- cross-encoding compression levels. - */ - -/* - * Reserved range for TDE: - * 0xFFFE0100 - 0xFFFE01FF - */ - -#define rfbEncodingBackground 0xFFFE0125 - -#define rfbEncodingCompressLevel0 0xFFFFFF00 -#define rfbEncodingCompressLevel1 0xFFFFFF01 -#define rfbEncodingCompressLevel2 0xFFFFFF02 -#define rfbEncodingCompressLevel3 0xFFFFFF03 -#define rfbEncodingCompressLevel4 0xFFFFFF04 -#define rfbEncodingCompressLevel5 0xFFFFFF05 -#define rfbEncodingCompressLevel6 0xFFFFFF06 -#define rfbEncodingCompressLevel7 0xFFFFFF07 -#define rfbEncodingCompressLevel8 0xFFFFFF08 -#define rfbEncodingCompressLevel9 0xFFFFFF09 - -#define rfbEncodingXCursor 0xFFFFFF10 -#define rfbEncodingRichCursor 0xFFFFFF11 -#define rfbEncodingSoftCursor 0xFFFFFF12 -#define rfbEncodingPointerPos 0xFFFFFF18 - -#define rfbEncodingLastRect 0xFFFFFF20 - -#define rfbEncodingQualityLevel0 0xFFFFFFE0 -#define rfbEncodingQualityLevel1 0xFFFFFFE1 -#define rfbEncodingQualityLevel2 0xFFFFFFE2 -#define rfbEncodingQualityLevel3 0xFFFFFFE3 -#define rfbEncodingQualityLevel4 0xFFFFFFE4 -#define rfbEncodingQualityLevel5 0xFFFFFFE5 -#define rfbEncodingQualityLevel6 0xFFFFFFE6 -#define rfbEncodingQualityLevel7 0xFFFFFFE7 -#define rfbEncodingQualityLevel8 0xFFFFFFE8 -#define rfbEncodingQualityLevel9 0xFFFFFFE9 - - -/***************************************************************************** - * - * 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 [<bgpixel><subrect><subrect>...] where each <subrect> is - * [<pixel><rfbRectangle>]. - */ - -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 - * [<bgpixel><subrect><subrect>...] where each <subrect> is - * [<pixel><rfbCoRRERectangle>]. 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) - - -/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * zlib - zlib compressed Encoding. We have an rfbZlibHeader structure - * giving the number of bytes following. Finally the data follows is - * zlib compressed version of the raw pixel data as negotiated. - */ - -typedef struct { - CARD32 nBytes; -} rfbZlibHeader; - -#define sz_rfbZlibHeader 4 - - -/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Tight Encoding. - * - *-- The first byte of each Tight-encoded rectangle is a "compression control - * byte". Its format is as follows (bit 0 is the least significant one): - * - * bit 0: if 1, then compression stream 0 should be reset; - * bit 1: if 1, then compression stream 1 should be reset; - * bit 2: if 1, then compression stream 2 should be reset; - * bit 3: if 1, then compression stream 3 should be reset; - * bits 7-4: if 1000 (0x08), then the compression type is "fill", - * if 1001 (0x09), then the compression type is "jpeg", - * if 0xxx, then the compression type is "basic", - * values greater than 1001 are not valid. - * - * If the compression type is "basic", then bits 6..4 of the - * compression control byte (those xxx in 0xxx) specify the following: - * - * bits 5-4: decimal representation is the index of a particular zlib - * stream which should be used for decompressing the data; - * bit 6: if 1, then a "filter id" byte is following this byte. - * - *-- The data that follows after the compression control byte described - * above depends on the compression type ("fill", "jpeg" or "basic"). - * - *-- If the compression type is "fill", then the only pixel value follows, in - * client pixel format (see NOTE 1). This value applies to all pixels of the - * rectangle. - * - *-- If the compression type is "jpeg", the following data stream looks like - * this: - * - * 1..3 bytes: data size (N) in compact representation; - * N bytes: JPEG image. - * - * Data size is compactly represented in one, two or three bytes, according - * to the following scheme: - * - * 0xxxxxxx (for values 0..127) - * 1xxxxxxx 0yyyyyyy (for values 128..16383) - * 1xxxxxxx 1yyyyyyy zzzzzzzz (for values 16384..4194303) - * - * Here each character denotes one bit, xxxxxxx are the least significant 7 - * bits of the value (bits 0-6), yyyyyyy are bits 7-13, and zzzzzzzz are the - * most significant 8 bits (bits 14-21). For example, decimal value 10000 - * should be represented as two bytes: binary 10010000 01001110, or - * hexadecimal 90 4E. - * - *-- If the compression type is "basic" and bit 6 of the compression control - * byte was set to 1, then the next (second) byte specifies "filter id" which - * tells the decoder what filter type was used by the encoder to pre-process - * pixel data before the compression. The "filter id" byte can be one of the - * following: - * - * 0: no filter ("copy" filter); - * 1: "palette" filter; - * 2: "gradient" filter. - * - *-- If bit 6 of the compression control byte is set to 0 (no "filter id" - * byte), or if the filter id is 0, then raw pixel values in the client - * format (see NOTE 1) will be compressed. See below details on the - * compression. - * - *-- The "gradient" filter pre-processes pixel data with a simple algorithm - * which converts each color component to a difference between a "predicted" - * intensity and the actual intensity. Such a technique does not affect - * uncompressed data size, but helps to compress photo-like images better. - * Pseudo-code for converting intensities to differences is the following: - * - * P[i,j] := V[i-1,j] + V[i,j-1] - V[i-1,j-1]; - * if (P[i,j] < 0) then P[i,j] := 0; - * if (P[i,j] > MAX) then P[i,j] := MAX; - * D[i,j] := V[i,j] - P[i,j]; - * - * Here V[i,j] is the intensity of a color component for a pixel at - * coordinates (i,j). MAX is the maximum value of intensity for a color - * component. - * - *-- The "palette" filter converts true-color pixel data to indexed colors - * and a palette which can consist of 2..256 colors. If the number of colors - * is 2, then each pixel is encoded in 1 bit, otherwise 8 bits is used to - * encode one pixel. 1-bit encoding is performed such way that the most - * significant bits correspond to the leftmost pixels, and each raw of pixels - * is aligned to the byte boundary. When "palette" filter is used, the - * palette is sent before the pixel data. The palette begins with an unsigned - * byte which value is the number of colors in the palette minus 1 (i.e. 1 - * means 2 colors, 255 means 256 colors in the palette). Then follows the - * palette itself which consist of pixel values in client pixel format (see - * NOTE 1). - * - *-- The pixel data is compressed using the zlib library. But if the data - * size after applying the filter but before the compression is less then 12, - * then the data is sent as is, uncompressed. Four separate zlib streams - * (0..3) can be used and the decoder should read the actual stream id from - * the compression control byte (see NOTE 2). - * - * If the compression is not used, then the pixel data is sent as is, - * otherwise the data stream looks like this: - * - * 1..3 bytes: data size (N) in compact representation; - * N bytes: zlib-compressed data. - * - * Data size is compactly represented in one, two or three bytes, just like - * in the "jpeg" compression method (see above). - * - *-- NOTE 1. If the color depth is 24, and all three color components are - * 8-bit wide, then one pixel in Tight encoding is always represented by - * three bytes, where the first byte is red component, the second byte is - * green component, and the third byte is blue component of the pixel color - * value. This applies to colors in palettes as well. - * - *-- NOTE 2. The decoder must reset compression streams' states before - * decoding the rectangle, if some of bits 0,1,2,3 in the compression control - * byte are set to 1. Note that the decoder must reset zlib streams even if - * the compression type is "fill" or "jpeg". - * - *-- NOTE 3. The "gradient" filter and "jpeg" compression may be used only - * when bits-per-pixel value is either 16 or 32, not 8. - * - *-- NOTE 4. The width of any Tight-encoded rectangle cannot exceed 2048 - * pixels. If a rectangle is wider, it must be split into several rectangles - * and each one should be encoded separately. - * - */ - -#define rfbTightExplicitFilter 0x04 -#define rfbTightFill 0x08 -#define rfbTightJpeg 0x09 -#define rfbTightMaxSubencoding 0x09 - -/* Filters to improve compression efficiency */ -#define rfbTightFilterCopy 0x00 -#define rfbTightFilterPalette 0x01 -#define rfbTightFilterGradient 0x02 - - -/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * XCursor encoding. This is a special encoding used to transmit X-style - * cursor shapes from server to clients. Note that for this encoding, - * coordinates in rfbFramebufferUpdateRectHeader structure hold hotspot - * position (r.x, r.y) and cursor size (r.w, r.h). If (w * h != 0), two RGB - * samples are sent after header in the rfbXCursorColors structure. They - * denote foreground and background colors of the cursor. If a client - * supports only black-and-white cursors, it should ignore these colors and - * assume that foreground is black and background is white. Next, two bitmaps - * (1 bits per pixel) follow: first one with actual data (value 0 denotes - * background color, value 1 denotes foreground color), second one with - * transparency data (bits with zero value mean that these pixels are - * transparent). Both bitmaps represent cursor data in a byte stream, from - * left to right, from top to bottom, and each row is byte-aligned. Most - * significant bits correspond to leftmost pixels. The number of bytes in - * each row can be calculated as ((w + 7) / 8). If (w * h == 0), cursor - * should be hidden (or default local cursor should be set by the client). - */ - -typedef struct { - CARD8 foreRed; - CARD8 foreGreen; - CARD8 foreBlue; - CARD8 backRed; - CARD8 backGreen; - CARD8 backBlue; -} rfbXCursorColors; - -#define sz_rfbXCursorColors 6 - - -/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * RichCursor encoding. This is a special encoding used to transmit cursor - * shapes from server to clients. It is similar to the XCursor encoding but - * uses client pixel format instead of two RGB colors to represent cursor - * image. For this encoding, coordinates in rfbFramebufferUpdateRectHeader - * structure hold hotspot position (r.x, r.y) and cursor size (r.w, r.h). - * After header, two pixmaps follow: first one with cursor image in current - * client pixel format (like in raw encoding), second with transparency data - * (1 bit per pixel, exactly the same format as used for transparency bitmap - * in the XCursor encoding). If (w * h == 0), cursor should be hidden (or - * default local cursor should be set by the client). - */ - - -/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * SoftCursor encoding. This encoding is used to transmit image and position - * of the remote cursor. It has two sub-messages: SetImage is used to upload - * one of 16 images, and Move selects the image and sets the position of the - * cursor. - * Each SoftCursor message starts with a CARD8. If it is in the 0-15 range - * it specifies the number of the cursor image and is followed by the - * rfbSoftCursorMove message. If the given cursor has not been set yet the - * message will be ignored. If the first CARD8 is in the 128-143 range it - * specifies the cursor that will be set in the following - * rfbSoftCursorSetImage message. To hide the cursor send a SetImage - * message with width and height 0 and imageLength 0. - * SetImage transmits the hotspot coordinates in the x/y fields of the - * rfbFramebufferUpdateRectHeader, width and height of the image are in the - * header's width and height fields. - * Move transmits the pointer coordinates in the w/h fields of the - * header, x/y are always 0. - */ - -typedef struct { - CARD8 imageIndex; - CARD8 buttonMask; /* bits 0-7 are buttons 1-8, 0=up, 1=down */ -} rfbSoftCursorMove; - -typedef struct { - CARD8 imageIndex; - CARD8 padding; - CARD16 imageLength; - /* - * Followed by an image of the cursor in the client's image format - * with the following RLE mask compression. It begins with CARD8 that - * specifies the number of mask'ed pixels that will be NOT transmitted. - * Then follows a CARD8 that specified by the number of unmask'd pixels - * that will be transmitted next. Then a CARD8 with the number of mask'd - * pixels and so on. - */ -} rfbSoftCursorSetImage; - -typedef union { - CARD8 type; - rfbSoftCursorMove move; - rfbSoftCursorSetImage setImage; -} rfbSoftCursorMsg; - -#define rfbSoftCursorMaxImages 16 -#define rfbSoftCursorSetIconOffset 128 - -/*----------------------------------------------------------------------------- - * 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 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/krdc/vnc/scaling.cpp b/krdc/vnc/scaling.cpp new file mode 100644 index 00000000..b79b8873 --- /dev/null +++ b/krdc/vnc/scaling.cpp @@ -0,0 +1,331 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net> +** +** This file is part of TDE. +** +** 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; see the file COPYING. If not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +** Boston, MA 02110-1301, USA. +** +****************************************************************************/ + +#include <tqimage.h> + +/*! + + Smooth scaling function with ability to limit scaled region + The selection rectangle is given in terms of destination coordinates + It leaves areas outside of the selection rectangle undefined... + + Function code originally taken from qimage.cpp pnmscale () and modified + to only scale a section of the source + + This function uses code based on pnmscale.c by Jef Poskanzer. + + pnmscale.c - read a portable anymap and scale it + + \legalese + + Copyright (C) 1989, 1991 by Jef Poskanzer. + + 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. This software is + provided "as is" without express or implied warranty. + +*/ + +void pnmscale_fractional(const TQImage& src, TQImage& dst, int x, int y, int w, int h) +{ + TQRgb* xelrow = 0; + TQRgb* tempxelrow = 0; + register TQRgb* xP; + register TQRgb* nxP; + int rows, cols, rowsread, newrows, newcols; + register int row, col, needtoreadrow; + const uchar maxval = 255; + double xscale, yscale; + long sxscale, syscale; + register long fracrowtofill, fracrowleft; + long* as; + long* rs; + long* gs; + long* bs; + int rowswritten = 0; + int colswritten = 0; + + cols = src.width(); + rows = src.height(); + newcols = dst.width(); + newrows = dst.height(); + + long SCALE; + long HALFSCALE; + + if (cols > 4096) + { + SCALE = 4096; + HALFSCALE = 2048; + } + else + { + int fac = 4096; + + while (cols * fac > 4096) + { + fac /= 2; + } + + SCALE = fac * cols; + HALFSCALE = fac * cols / 2; + } + + xscale = (double) newcols / (double) cols; + yscale = (double) newrows / (double) rows; + + sxscale = (long)(xscale * SCALE); + syscale = (long)(yscale * SCALE); + + if ( newrows != rows ) /* shortcut Y scaling if possible */ + tempxelrow = new TQRgb[cols]; + + if ( src.hasAlphaBuffer() ) { + dst.setAlphaBuffer(TRUE); + as = new long[cols]; + for ( col = 0; col < cols; ++col ) + as[col] = HALFSCALE; + } else { + as = 0; + } + rs = new long[cols]; + gs = new long[cols]; + bs = new long[cols]; + rowsread = 0; + fracrowleft = syscale; + needtoreadrow = 1; + for ( col = 0; col < cols; ++col ) + rs[col] = gs[col] = bs[col] = HALFSCALE; + fracrowtofill = SCALE; + + for ( row = 0; row < newrows; ++row ) { + /* First scale Y from xelrow into tempxelrow. */ + if ( newrows == rows ) { + /* shortcut Y scaling if possible */ + tempxelrow = xelrow = (TQRgb*)src.scanLine(rowsread++); + } else { + while ( fracrowleft < fracrowtofill ) { + if ( needtoreadrow && rowsread < rows ) + xelrow = (TQRgb*)src.scanLine(rowsread++); + for ( col = 0, xP = xelrow; col < cols; ++col, ++xP ) { +if ((rowswritten >= y) && (rowswritten <= (y + h))) { + if (as) { + as[col] += fracrowleft * tqAlpha( *xP ); + rs[col] += fracrowleft * tqRed( *xP ) * tqAlpha( *xP ) / 255; + gs[col] += fracrowleft * tqGreen( *xP ) * tqAlpha( *xP ) / 255; + bs[col] += fracrowleft * tqBlue( *xP ) * tqAlpha( *xP ) / 255; + } else { + rs[col] += fracrowleft * tqRed( *xP ); + gs[col] += fracrowleft * tqGreen( *xP ); + bs[col] += fracrowleft * tqBlue( *xP ); + } +} + } + fracrowtofill -= fracrowleft; + fracrowleft = syscale; + needtoreadrow = 1; + } + /* Now fracrowleft is >= fracrowtofill, so we can produce a row. */ + if ( needtoreadrow && rowsread < rows ) { + xelrow = (TQRgb*)src.scanLine(rowsread++); + needtoreadrow = 0; + } + register long a=0; + for ( col = 0, xP = xelrow, nxP = tempxelrow, colswritten = 0; + col < cols; ++col, ++xP, ++nxP, ++colswritten ) + { +if ((rowswritten >= y) && (rowswritten <= (y + h))) { + register long r, g, b; + + if ( as ) { + r = rs[col] + fracrowtofill * tqRed( *xP ) * tqAlpha( *xP ) / 255; + g = gs[col] + fracrowtofill * tqGreen( *xP ) * tqAlpha( *xP ) / 255; + b = bs[col] + fracrowtofill * tqBlue( *xP ) * tqAlpha( *xP ) / 255; + a = as[col] + fracrowtofill * tqAlpha( *xP ); + if ( a ) { + r = r * 255 / a * SCALE; + g = g * 255 / a * SCALE; + b = b * 255 / a * SCALE; + } + } else { + r = rs[col] + fracrowtofill * tqRed( *xP ); + g = gs[col] + fracrowtofill * tqGreen( *xP ); + b = bs[col] + fracrowtofill * tqBlue( *xP ); + } + r /= SCALE; + if ( r > maxval ) r = maxval; + g /= SCALE; + if ( g > maxval ) g = maxval; + b /= SCALE; + if ( b > maxval ) b = maxval; + if ( as ) { + a /= SCALE; + if ( a > maxval ) a = maxval; + *nxP = tqRgba( (int)r, (int)g, (int)b, (int)a ); + as[col] = HALFSCALE; + } else { + *nxP = tqRgb( (int)r, (int)g, (int)b ); + } + rs[col] = gs[col] = bs[col] = HALFSCALE; +} + } + fracrowleft -= fracrowtofill; + if ( fracrowleft == 0 ) { + fracrowleft = syscale; + needtoreadrow = 1; + } + fracrowtofill = SCALE; + } + + /* Now scale X from tempxelrow into dst and write it out. */ + if ( newcols == cols ) { + /* shortcut X scaling if possible */ + memcpy(dst.scanLine(rowswritten++), tempxelrow, newcols*4); + } else { + register long a, r, g, b; + register long fraccoltofill, fraccolleft = 0; + register int needcol; + + nxP = (TQRgb*)dst.scanLine(rowswritten++); + colswritten = 0; + fraccoltofill = SCALE; + a = r = g = b = HALFSCALE; + needcol = 0; + for ( col = 0, xP = tempxelrow; col < cols; ++col, ++xP ) { + fraccolleft = sxscale; + while ( fraccolleft >= fraccoltofill ) { + if ( needcol ) { + ++nxP; + ++colswritten; + a = r = g = b = HALFSCALE; + } +if ((colswritten >= x) && (colswritten <= (x + w)) && (rowswritten >= y) && (rowswritten <= (y + h))) { + if ( as ) { + r += fraccoltofill * tqRed( *xP ) * tqAlpha( *xP ) / 255; + g += fraccoltofill * tqGreen( *xP ) * tqAlpha( *xP ) / 255; + b += fraccoltofill * tqBlue( *xP ) * tqAlpha( *xP ) / 255; + a += fraccoltofill * tqAlpha( *xP ); + if ( a ) { + r = r * 255 / a * SCALE; + g = g * 255 / a * SCALE; + b = b * 255 / a * SCALE; + } + } else { + r += fraccoltofill * tqRed( *xP ); + g += fraccoltofill * tqGreen( *xP ); + b += fraccoltofill * tqBlue( *xP ); + } + r /= SCALE; + if ( r > maxval ) r = maxval; + g /= SCALE; + if ( g > maxval ) g = maxval; + b /= SCALE; + if ( b > maxval ) b = maxval; + if (as) { + a /= SCALE; + if ( a > maxval ) a = maxval; + *nxP = tqRgba( (int)r, (int)g, (int)b, (int)a ); + } else { + *nxP = tqRgb( (int)r, (int)g, (int)b ); + } +} + fraccolleft -= fraccoltofill; + fraccoltofill = SCALE; + needcol = 1; + } + if ( fraccolleft > 0 ) { + if ( needcol ) { + ++nxP; + ++colswritten; + a = r = g = b = HALFSCALE; + needcol = 0; + } +if ((rowswritten >= y) && (rowswritten <= (y + h))) { + if (as) { + a += fraccolleft * tqAlpha( *xP ); + r += fraccolleft * tqRed( *xP ) * tqAlpha( *xP ) / 255; + g += fraccolleft * tqGreen( *xP ) * tqAlpha( *xP ) / 255; + b += fraccolleft * tqBlue( *xP ) * tqAlpha( *xP ) / 255; + } else { + r += fraccolleft * tqRed( *xP ); + g += fraccolleft * tqGreen( *xP ); + b += fraccolleft * tqBlue( *xP ); + } +} + fraccoltofill -= fraccolleft; + } + } + if ( fraccoltofill > 0 ) { + --xP; +if ((rowswritten >= y) && (rowswritten <= (y + h))) { + if (as) { + a += fraccolleft * tqAlpha( *xP ); + r += fraccoltofill * tqRed( *xP ) * tqAlpha( *xP ) / 255; + g += fraccoltofill * tqGreen( *xP ) * tqAlpha( *xP ) / 255; + b += fraccoltofill * tqBlue( *xP ) * tqAlpha( *xP ) / 255; + if ( a ) { + r = r * 255 / a * SCALE; + g = g * 255 / a * SCALE; + b = b * 255 / a * SCALE; + } + } else { + r += fraccoltofill * tqRed( *xP ); + g += fraccoltofill * tqGreen( *xP ); + b += fraccoltofill * tqBlue( *xP ); + } +} + } + if ( ! needcol ) { +if ((rowswritten >= y) && (rowswritten <= (y + h))) { + r /= SCALE; + if ( r > maxval ) r = maxval; + g /= SCALE; + if ( g > maxval ) g = maxval; + b /= SCALE; + if ( b > maxval ) b = maxval; + if (as) { + a /= SCALE; + if ( a > maxval ) a = maxval; + *nxP = tqRgba( (int)r, (int)g, (int)b, (int)a ); + } else { + *nxP = tqRgb( (int)r, (int)g, (int)b ); + } +} + } + } + } + + if ( newrows != rows && tempxelrow )// Robust, tempxelrow might be 0 1 day + delete [] tempxelrow; + if ( as ) // Avoid purify complaint + delete [] as; + if ( rs ) // Robust, rs might be 0 one day + delete [] rs; + if ( gs ) // Robust, gs might be 0 one day + delete [] gs; + if ( bs ) // Robust, bs might be 0 one day + delete [] bs; +} diff --git a/krdc/vnc/sockets.c b/krdc/vnc/sockets.c deleted file mode 100644 index aedf59ec..00000000 --- a/krdc/vnc/sockets.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * 03-05-2002 tim@tjansen.de: removed Xt event processing for krdc - */ - -/* - * sockets.c - functions to deal with sockets. - */ - -#include <unistd.h> -#include <sys/socket.h> -#include <errno.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <fcntl.h> -#include <assert.h> -#include "vncviewer.h" - -void PrintInHex(char *buf, int len); - -Bool errorMessageOnReadFailure = True; - -#define BUF_SIZE 8192 -static char buf[BUF_SIZE]; -static char *bufoutptr = buf; -static unsigned int buffered = 0; - -/* Wait duration of select in seconds */ -#define SELECT_PERIOD 3 - - -/* - * ReadFromRFBServer is called whenever we want to read some data from the RFB - * server. - */ -Bool -ReadFromRFBServer(char *out, unsigned int n) -{ - fd_set fds; - int e; - struct timeval tx; - - if (isQuitFlagSet()) - return False; - - if (n <= buffered) { - memcpy(out, bufoutptr, n); - bufoutptr += n; - buffered -= n; - return True; - } - - memcpy(out, bufoutptr, buffered); - - out += buffered; - n -= buffered; - - bufoutptr = buf; - buffered = 0; - - if (n <= BUF_SIZE) { - - while (buffered < n) { - int i; - if (isQuitFlagSet()) - return False; - i = read(rfbsock, buf + buffered, BUF_SIZE - buffered); - - if (i <= 0) { - if (i < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) { - FD_ZERO(&fds); - FD_SET(rfbsock,&fds); - - tx.tv_sec = SELECT_PERIOD; - tx.tv_usec = 0; - if ((e=select(rfbsock+1, &fds, NULL, &fds, &tx)) < 0) { - perror("krdc: select read"); - return False; - } - i = 0; - } else { - perror("krdc: read"); - return False; - } - } else { - fprintf(stderr,"VNC server closed connection\n"); - return False; - } - } - buffered += i; - } - - memcpy(out, bufoutptr, n); - bufoutptr += n; - buffered -= n; - return isQuitFlagSet() ? False : True; - - } else { - - while (n > 0) { - int i; - if (isQuitFlagSet()) - return False; - i = read(rfbsock, out, n); - if (i <= 0) { - if (i < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) { - FD_ZERO(&fds); - FD_SET(rfbsock,&fds); - - tx.tv_sec = SELECT_PERIOD; - tx.tv_usec = 0; - if ((e=select(rfbsock+1, &fds, NULL, &fds, &tx)) < 0) { - perror("krdc: select"); - return False; - } - i = 0; - } else { - perror("krdc: read"); - return False; - } - } else { - fprintf(stderr,"VNC server closed connection\n"); - return False; - } - } - out += i; - n -= i; - } - - return isQuitFlagSet() ? False : True; - } -} - - -/* - * Write an exact number of bytes, and don't return until you've sent them. - * Note: this should only be called by the WriterThread - */ - -Bool -WriteExact(int sock, const char *_buf, int n) -{ - fd_set fds; - int i = 0; - int j; - int e; - struct timeval tx; - - while (i < n) { - if (isQuitFlagSet()) - return False; - j = write(sock, _buf + i, (n - i)); - if (j <= 0) { - if (j < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) { - FD_ZERO(&fds); - FD_SET(rfbsock,&fds); - - tx.tv_sec = SELECT_PERIOD; - tx.tv_usec = 0; - if ((e=select(rfbsock+1, NULL, &fds, NULL, &tx)) < 0) { - perror("krdc: select write"); - return False; - } - j = 0; - } else { - perror("krdc: write"); - return False; - } - } else { - fprintf(stderr,"write failed\n"); - return False; - } - } - i += j; - } - return True; -} - - -/* - * ConnectToTcpAddr connects to the given TCP port. - */ - -int -ConnectToTcpAddr(unsigned int host, int port) -{ - int sock; - struct sockaddr_in addr; - int one = 1; - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = host; - - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) { - perror("krdc: ConnectToTcpAddr: socket"); - return -(int)INIT_CONNECTION_FAILED; - } - - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - perror("krdc: ConnectToTcpAddr: connect"); - close(sock); - return -(int)INIT_NO_SERVER; - } - - if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, - (char *)&one, sizeof(one)) < 0) { - perror("krdc: ConnectToTcpAddr: setsockopt"); - close(sock); - return -(int)INIT_CONNECTION_FAILED; - } - - if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { - perror(": AcceptTcpConnection: fcntl"); - close(sock); - return -(int)INIT_CONNECTION_FAILED; - } - - return sock; -} - - -/* - * StringToIPAddr - convert a host string to an IP address. - */ - -Bool -StringToIPAddr(const char *str, unsigned int *addr) -{ - struct hostent *hp; - - if (strcmp(str,"") == 0) { - *addr = 0; /* local */ - return True; - } - - *addr = inet_addr(str); - - if (*addr != -1) - return True; - - hp = gethostbyname(str); - - if (hp) { - *addr = *(unsigned int *)hp->h_addr; - return True; - } - - return False; -} - - -/* - * Print out the contents of a packet for debugging. - */ - -void -PrintInHex(char *_buf, int len) -{ - int i, j; - char c, str[17]; - - str[16] = 0; - - fprintf(stderr,"ReadExact: "); - - for (i = 0; i < len; i++) - { - if ((i % 16 == 0) && (i != 0)) { - fprintf(stderr," "); - } - c = _buf[i]; - str[i % 16] = (((c > 31) && (c < 127)) ? c : '.'); - fprintf(stderr,"%02x ",(unsigned char)c); - if ((i % 4) == 3) - fprintf(stderr," "); - if ((i % 16) == 15) - { - fprintf(stderr,"%s\n",str); - } - } - if ((i % 16) != 0) - { - for (j = i % 16; j < 16; j++) - { - fprintf(stderr," "); - if ((j % 4) == 3) fprintf(stderr," "); - } - str[i % 16] = 0; - fprintf(stderr,"%s\n",str); - } - - fflush(stderr); -} - -void freeSocketsResources() { - close(rfbsock); - - errorMessageOnReadFailure = True; - bufoutptr = buf; - buffered = 0; -} - diff --git a/krdc/vnc/threads.cpp b/krdc/vnc/threads.cpp index cf32d081..860511e9 100644 --- a/krdc/vnc/threads.cpp +++ b/krdc/vnc/threads.cpp @@ -2,7 +2,8 @@ threads.cpp - threads ------------------- begin : Thu May 09 17:01:44 CET 2002 - copyright : (C) 2002 by Tim Jansen + copyright : (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net> + (C) 2002 by Tim Jansen email : tim@tjansen.de ***************************************************************************/ @@ -24,369 +25,360 @@ #include "threads.h" #include <tqcstring.h> +#include <tqpainter.h> -// Maximum idle time for writer thread in ms. When it timeouts, it will request -// another incremental update. Must be smaller than the timeout of the server -// (krfb's is 20s). -static const int MAXIMUM_WAIT_PERIOD = 8000; +#include <math.h> -// time to postpone incremental updates that have not been requested explicitly -static const int POSTPONED_INCRRQ_WAIT_PERIOD = 110; +extern void pnmscale_fractional(const TQImage& src, TQImage& dst, int x, int y, int w, int h); -static const int MOUSEPRESS_QUEUE_SIZE = 5; -static const int MOUSEMOVE_QUEUE_SIZE = 3; -static const int KEY_QUEUE_SIZE = 8192; +int getPassword(char * &passwd); - -ControllerThread::ControllerThread(KVncView *v, WriterThread &wt, volatile bool &quitFlag) : - m_view(v), - m_status(REMOTE_VIEW_CONNECTING), - m_wthread(wt), - m_quitFlag(quitFlag), - m_desktopInitialized(false) +extern rfbBool newclient(rfbClient *cl) { + int width = cl->width, height = cl->height, depth = cl->format.bitsPerPixel; + int size = width * height * (depth / 8); + uint8_t *buf = new uint8_t[size]; + memset(buf, '\0', size); + cl->frameBuffer = buf; + cl->format.bitsPerPixel = 32; + cl->format.redShift = 16; + cl->format.greenShift = 8; + cl->format.blueShift = 0; + cl->format.redMax = 0xff; + cl->format.greenMax = 0xff; + cl->format.blueMax = 0xff; + + SetFormatAndEncodings(cl); + + return true; } -void ControllerThread::changeStatus(RemoteViewStatus s) { - m_status = s; - TQApplication::postEvent(m_view, new StatusChangeEvent(s)); +extern void updatefb(rfbClient* cl, int x, int y, int w, int h) +{ +// kdDebug(5011) << "updated client: x: " << x << ", y: " << y << ", w: " << w << ", h: " << h << endl; + + int width = cl->width, height = cl->height; + + TQImage img(cl->frameBuffer, width, height, 32, NULL, 256, TQImage::IgnoreEndian); + + if (img.isNull()) + kdDebug(5011) << "image not loaded" << endl; + + + ControllerThreadObject *t = (ControllerThreadObject*)rfbClientGetClientData(cl, 0); + + t->setImage(img); + t->queueDrawRegion(x, y, w, h); } -void ControllerThread::sendFatalError(ErrorCode s) { - m_quitFlag = true; - TQApplication::postEvent(m_view, new FatalErrorEvent(s)); - m_wthread.kick(); +extern char *passwd(rfbClient *cl) +{ + Q_UNUSED(cl) + + kdDebug(5011) << "password request" << endl; + + char *passwd; + if (getPassword(passwd)) { + return passwd; + } + else { + return NULL; + } } -/* - * Calls this from the X11 thread - */ -void ControllerThread::desktopInit() { - SetVisualAndCmap(); - ToplevelInit(); - DesktopInit(m_view->winId()); - m_desktopInitialized = true; - m_waiter.wakeAll(); +extern void authresults(rfbClient *cl, uint32_t authResult) +{ + kdDebug(5011) << "authentication result: " << authResult << endl; + + ControllerThreadObject *t = (ControllerThreadObject*)rfbClientGetClientData(cl, 0); + + t->authenticationResults(authResult); } -void ControllerThread::kick() { - m_waiter.wakeAll(); +extern void networkstat(rfbClient *cl, uint32_t statuscode) +{ + kdDebug(5011) << "network status: " << statuscode << endl; + + ControllerThreadObject *t = (ControllerThreadObject*)rfbClientGetClientData(cl, 0); + + t->networkStatus(statuscode); } -void ControllerThread::run() { - int fd; - fd = ConnectToRFBServer(m_view->host().latin1(), m_view->port()); - if (fd < 0) { - if (fd == -(int)INIT_NO_SERVER) - sendFatalError(ERROR_NO_SERVER); - else if (fd == -(int)INIT_NAME_RESOLUTION_FAILURE) - sendFatalError(ERROR_NAME); - else - sendFatalError(ERROR_CONNECTION); - return; +extern void output(const char *format, ...) +{ + va_list args; + va_start(args, format); + + TQString message; + message.vsprintf(format, args); + + va_end(args); + + kdDebug(5011) << message.local8Bit(); + + if (message.contains("Could not open")) { + kdDebug(5011) << "Server not found!" << endl; } - if (m_quitFlag) { - changeStatus(REMOTE_VIEW_DISCONNECTED); - return; + + if (message.contains("VNC authentication succeeded")) { + kdDebug(5011) << "Password OK" << endl; } +} - changeStatus(REMOTE_VIEW_AUTHENTICATING); +ControllerThreadObject::ControllerThreadObject(KVncView *v, volatile bool &quitFlag) : + cl(0L), + m_view(v), + m_status(REMOTE_VIEW_CONNECTING), + m_quitFlag(quitFlag), + m_scaling(false), + m_scalingWidth(-1), + m_scalingHeight(-1), + m_resizeEntireFrame(false) +{ + TQMutexLocker locker(&mutex); - enum InitStatus s = InitialiseRFBConnection(); - if (s != INIT_OK) { - if (s == INIT_CONNECTION_FAILED) - sendFatalError(ERROR_IO); - else if (s == INIT_SERVER_BLOCKED) - sendFatalError(ERROR_SERVER_BLOCKED); - else if (s == INIT_PROTOCOL_FAILURE) - sendFatalError(ERROR_PROTOCOL); - else if (s == INIT_AUTHENTICATION_FAILED) - sendFatalError(ERROR_AUTHENTICATION); - else if (s == INIT_ABORTED) - changeStatus(REMOTE_VIEW_DISCONNECTED); - else - sendFatalError(ERROR_INTERNAL); - return; - } + cl = rfbGetClient(8, 3, 4); +} - TQApplication::postEvent(m_view, - new ScreenResizeEvent(si.framebufferWidth, - si.framebufferHeight)); - m_wthread.queueUpdateRequest(TQRegion(TQRect(0,0,si.framebufferWidth, - si.framebufferHeight))); +ControllerThreadObject::~ControllerThreadObject() { + TQMutexLocker locker(&mutex); - TQApplication::postEvent(m_view, new DesktopInitEvent()); - while ((!m_quitFlag) && (!m_desktopInitialized)) - m_waiter.wait(1000); + rfbClientCleanup(cl); +} - if (m_quitFlag) { - changeStatus(REMOTE_VIEW_DISCONNECTED); - return; - } +void ControllerThreadObject::changeStatus(RemoteViewStatus s) { + m_status = s; + TQApplication::postEvent(m_view, new StatusChangeEvent(s)); +} - changeStatus(REMOTE_VIEW_PREPARING); +void ControllerThreadObject::sendFatalError(ErrorCode s) { + m_quitFlag = true; + TQApplication::postEvent(m_view, new FatalErrorEvent(s)); +} - if (!SetFormatAndEncodings()) { - sendFatalError(ERROR_INTERNAL); - return; - } +void ControllerThreadObject::queueDrawRegion(int x, int y, int w, int h) { + if (m_scaling) { + // Rescale desktop - changeStatus(REMOTE_VIEW_CONNECTED); + int new_x; + int new_y; + int new_w; + int new_h; - m_wthread.start(); + mutex.lock(); - while (!m_quitFlag) { - if ((!HandleRFBServerMessage()) && (!m_quitFlag)) { - sendFatalError(ERROR_IO); - return; - } - } + if (m_resizeEntireFrame) { + m_scaledImage.create(m_scalingWidth, m_scalingHeight, 32); - m_quitFlag = true; - changeStatus(REMOTE_VIEW_DISCONNECTED); - m_wthread.kick(); -} + new_x = 0; + new_y = 0; + new_w = m_scalingWidth; + new_h = m_scalingHeight; -enum RemoteViewStatus ControllerThread::status() { - return m_status; -} + TQImage scaledBlock = m_image.smoothScale(new_w, new_h); + bitBlt(&m_scaledImage, new_x, new_y, &scaledBlock, 0, 0, new_w, new_h); + m_resizeEntireFrame = false; + } + else { + // Extend redraw boundaries to avoid pixelation artifacts due to rounding errors + x = x - round((2.0 * m_image.width()) / m_scalingWidth); + y = y - round((2.0 * m_image.height()) / m_scalingHeight); + w = w + round((4.0 * m_image.width()) / m_scalingWidth); + h = h + round((4.0 * m_image.height()) / m_scalingHeight); + + if (x < 0) { + x = 0; + } + if (y < 0) { + y = 0; + } + if (w > m_image.width()) { + w = m_image.width(); + } + if (h > m_image.height()) { + h = m_image.height(); + } + new_x = round((x * m_scalingWidth) / m_image.width()); + new_y = round((y * m_scalingHeight) / m_image.height()); + new_w = round((w * m_scalingWidth) / m_image.width()); + new_h = round((h * m_scalingHeight) / m_image.height()); + TQImage scaledBlock(m_scalingWidth, m_scalingHeight, 32); + pnmscale_fractional(m_image, scaledBlock, new_x, new_y, new_w, new_h); + bitBlt(&m_scaledImage, new_x, new_y, &scaledBlock, new_x, new_y, new_w, new_h); + } + mutex.unlock(); -static WriterThread *writerThread; -void queueIncrementalUpdateRequest() { - writerThread->queueIncrementalUpdateRequest(); + DrawScreenRegion(new_x, new_y, new_w, new_h); + } + else { + DrawScreenRegion(x, y, w, h); + } } -void announceIncrementalUpdateRequest() { - writerThread->announceIncrementalUpdateRequest(); +void ControllerThreadObject::setImage(const TQImage &img) { + TQMutexLocker locker(&mutex); + + m_image = img; } +const TQImage ControllerThreadObject::image(int x, int y, int w, int h) { + TQMutexLocker locker(&mutex); -WriterThread::WriterThread(KVncView *v, volatile bool &quitFlag) : - m_quitFlag(quitFlag), - m_view(v), - m_lastIncrUpdatePostponed(false), - m_incrementalUpdateRQ(false), - m_incrementalUpdateAnnounced(false), - m_mouseEventNum(0), - m_keyEventNum(0), - m_clientCut(TQString()) -{ - writerThread = this; - m_lastIncrUpdate.start(); + if (m_scaling) { + return m_scaledImage.copy(x, y, w, h); + } + else { + return m_image.copy(x, y, w, h); + } } -bool WriterThread::sendIncrementalUpdateRequest() { - m_lastIncrUpdate.restart(); - return SendIncrementalFramebufferUpdateRequest(); -} +void ControllerThreadObject::setScaling(int w, int h) { + bool scale; -bool WriterThread::sendUpdateRequest(const TQRegion ®ion) { - TQMemArray<TQRect> r = region.rects(); - for (unsigned int i = 0; i < r.size(); i++) - if (!SendFramebufferUpdateRequest(r[i].x(), - r[i].y(), - r[i].width(), - r[i].height(), False)) - return false; - return true; -} + if (w <= 0) { + scale = false; + } + else { + scale = true; + } -bool WriterThread::sendInputEvents(const TQValueList<InputEvent> &events) { - TQValueList<InputEvent>::const_iterator it = events.begin(); - while (it != events.end()) { - if ((*it).type == KeyEventType) { - if (!SendKeyEvent((*it).e.k.k, (*it).e.k.down ? True : False)) - return false; - } - else - if (!SendPointerEvent((*it).e.m.x, (*it).e.m.y, (*it).e.m.buttons)) - return false; - it++; + if ((m_scalingWidth != w) || (m_scalingHeight = h) || (m_scaling != scale)) { + m_resizeEntireFrame = true; } - return true; -} -void WriterThread::queueIncrementalUpdateRequest() { - m_lock.lock(); - m_incrementalUpdateRQ = true; - m_waiter.wakeAll(); - m_lock.unlock(); + m_scaling = scale; + m_scalingWidth = w; + m_scalingHeight = h; } -void WriterThread::announceIncrementalUpdateRequest() { - m_lock.lock(); - m_incrementalUpdateAnnounced = true; - m_lock.unlock(); -} +void ControllerThreadObject::run() { + mutex.lock(); + rfbClientLog = output; + rfbClientErr = output; + cl->MallocFrameBuffer = newclient; + cl->canHandleNewFBSize = true; + cl->GetPassword = passwd; + cl->AuthenticationResults = authresults; + cl->NetworkStatus = networkstat; + cl->GotFrameBufferUpdate = updatefb; + rfbClientSetClientData(cl, 0, this); -void WriterThread::queueUpdateRequest(const TQRegion &r) { - m_lock.lock(); - m_updateRegionRQ += r; - m_waiter.wakeAll(); - m_lock.unlock(); -} + // make a copy of the host string... + char *host = (char*) malloc(m_view->host().length()); + strcpy(host, m_view->host().ascii()); -void WriterThread::queueMouseEvent(int x, int y, int buttonMask) { - InputEvent e; - e.type = MouseEventType; - e.e.m.x = x; - e.e.m.y = y; - e.e.m.buttons = buttonMask; - - m_lock.lock(); - if (m_mouseEventNum > 0) { - if ((e.e.m.x == m_lastMouseEvent.x) && - (e.e.m.y == m_lastMouseEvent.y) && - (e.e.m.buttons == m_lastMouseEvent.buttons)) { - m_lock.unlock(); - return; - } - if (m_mouseEventNum >= MOUSEPRESS_QUEUE_SIZE) { - m_lock.unlock(); + cl->serverHost = host; + + int port = m_view->port(); + if(port >= 0 && port < 100) // the user most likely used the short form (e.g. :1) + port += 5900; + cl->serverPort = port; + + mutex.unlock(); + + if(!rfbInitClient(cl, 0, 0)) { + sendFatalError(ERROR_INTERNAL); + // Terminate thread + TQThread::exit(); + return; + } + + TQApplication::postEvent(m_view, + new ScreenResizeEvent(cl->width, + cl->height)); + + changeStatus(REMOTE_VIEW_CONNECTED); + + while (!m_quitFlag) { + int i = WaitForMessage(cl, 500); + if (i < 0) { + m_quitFlag = true; + changeStatus(REMOTE_VIEW_DISCONNECTED); + + // Terminate thread + TQThread::exit(); return; } - if ((m_lastMouseEvent.buttons == buttonMask) && - (m_mouseEventNum >= MOUSEMOVE_QUEUE_SIZE)) { - m_lock.unlock(); - return; + if (i) { + if(!HandleRFBServerMessage(cl)) { + m_quitFlag = true; + changeStatus(REMOTE_VIEW_DISCONNECTED); + + // Terminate thread + TQThread::exit(); + return; + } } } - m_mouseEventNum++; - m_lastMouseEvent = e.e.m; + m_quitFlag = true; + changeStatus(REMOTE_VIEW_DISCONNECTED); - m_inputEvents.push_back(e); - m_waiter.wakeAll(); - m_lock.unlock(); + // Terminate thread + TQThread::exit(); } -void WriterThread::queueKeyEvent(unsigned int k, bool down) { - InputEvent e; - e.type = KeyEventType; - e.e.k.k = k; - e.e.k.down = down; - - m_lock.lock(); - if (m_keyEventNum >= KEY_QUEUE_SIZE) { - m_lock.unlock(); - return; +void ControllerThreadObject::authenticationResults(int resultCode) { + if (resultCode == rfbVncAuthOK) { + changeStatus(REMOTE_VIEW_PREPARING); } + else { + sendFatalError(ERROR_AUTHENTICATION); - m_keyEventNum++; - m_inputEvents.push_back(e); - m_waiter.wakeAll(); - m_lock.unlock(); + // Terminate thread + TQThread::exit(); + } } -void WriterThread::queueClientCut(const TQString &text) { - m_lock.lock(); - - m_clientCut = text; +void ControllerThreadObject::networkStatus(int statusCode) { + if (statusCode == rfbNetworkConnectionSuccess) { + // Stage 1 OK... + changeStatus(REMOTE_VIEW_AUTHENTICATING); + } + else if (statusCode == rfbNetworkRFBConnectionSuccess) { + // Stage 2 OK! + } + else { + if (statusCode == rfbNetworkConnectionClosed) { + sendFatalError(ERROR_CONNECTION); + } + else if (statusCode == rfbNetworkConnectionFailed) { + sendFatalError(ERROR_CONNECTION); + } + else if (statusCode == rfbNetworkNameResolutionFailed) { + sendFatalError(ERROR_NAME); + } + else if (statusCode == rfbNetworkRFBServerNotValid) { + sendFatalError(ERROR_IO); + } + else if (statusCode == rfbNetworkRFBProtocolFailure) { + sendFatalError(ERROR_PROTOCOL); + } + + // Terminate thread + TQThread::exit(); + } +} - m_waiter.wakeAll(); - m_lock.unlock(); +enum RemoteViewStatus ControllerThreadObject::status() { + return m_status; } -void WriterThread::kick() { - m_waiter.wakeAll(); +void ControllerThreadObject::queueMouseEvent(int x, int y, int buttonMask) { + SendPointerEvent(cl, x, y, buttonMask); } -void WriterThread::run() { - bool incrementalUpdateRQ = false; - bool incrementalUpdateAnnounced = false; - TQRegion updateRegionRQ; - TQValueList<InputEvent> inputEvents; - TQString clientCut; - - while (!m_quitFlag) { - m_lock.lock(); - incrementalUpdateRQ = m_incrementalUpdateRQ; - incrementalUpdateAnnounced = m_incrementalUpdateAnnounced; - updateRegionRQ = m_updateRegionRQ; - inputEvents = m_inputEvents; - clientCut = m_clientCut; - - if ((!incrementalUpdateRQ) && - (updateRegionRQ.isNull()) && - (inputEvents.size() == 0) && - (clientCut.isNull())) { - if (!m_waiter.wait(&m_lock, - m_lastIncrUpdatePostponed ? - POSTPONED_INCRRQ_WAIT_PERIOD : MAXIMUM_WAIT_PERIOD)) - m_incrementalUpdateRQ = true; - m_lock.unlock(); - } - else { - m_incrementalUpdateRQ = false; - m_incrementalUpdateAnnounced = false; - m_updateRegionRQ = TQRegion(); - m_inputEvents.clear(); - m_keyEventNum = 0; - m_mouseEventNum = 0; - m_clientCut = TQString(); - m_lock.unlock(); - - // always send incremental update, unless - // a) a framebuffer update is done ATM and will do the request later, or - // b) the last unrequested update has been done less than 0.1s ago - // - // if the update has not been done because of b, postpone it. - if (incrementalUpdateRQ || !incrementalUpdateAnnounced) { - bool sendUpdate; - if (incrementalUpdateRQ) { - sendUpdate = true; - m_lastIncrUpdatePostponed = false; - } - else { - if (m_lastIncrUpdate.elapsed() < 100) { - sendUpdate = false; - m_lastIncrUpdatePostponed = true; - } - else { - sendUpdate = true; - m_lastIncrUpdatePostponed = false; - } - } - - if (sendUpdate) - if (!sendIncrementalUpdateRequest()) { - sendFatalError(ERROR_IO); - break; - } - } - else - m_lastIncrUpdatePostponed = false; - - if (!updateRegionRQ.isNull()) - if (!sendUpdateRequest(updateRegionRQ)) { - sendFatalError(ERROR_IO); - break; - } - if (inputEvents.size() != 0) - if (!sendInputEvents(inputEvents)) { - sendFatalError(ERROR_IO); - break; - } - if (!clientCut.isNull()) { - TQCString cutTextUtf8(clientCut.utf8()); - if (!SendClientCutText(cutTextUtf8.data(), - (int)cutTextUtf8.length())) { - sendFatalError(ERROR_IO); - break; - } - } - } - } - m_quitFlag = true; +void ControllerThreadObject::queueKeyEvent(unsigned int k, bool down) { + SendKeyEvent(cl, k, down); } -void WriterThread::sendFatalError(ErrorCode s) { - m_quitFlag = true; - TQApplication::postEvent(m_view, new FatalErrorEvent(s)); +void ControllerThreadObject::queueClientCut(const TQString &text) { + SendClientCutText(cl, (char*)text.ascii(), text.length()); } +#include "threads.moc"
\ No newline at end of file diff --git a/krdc/vnc/threads.h b/krdc/vnc/threads.h index 08ca4c20..6b4d154e 100644 --- a/krdc/vnc/threads.h +++ b/krdc/vnc/threads.h @@ -2,7 +2,8 @@ threads.h - threads for kvncview ------------------- begin : Thu May 09 16:01:42 CET 2002 - copyright : (C) 2002 by Tim Jansen + copyright : (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net> + (C) 2002 by Tim Jansen email : tim@tjansen.de ***************************************************************************/ @@ -26,11 +27,15 @@ #include <tqevent.h> #include <tqvaluelist.h> #include <tqdatetime.h> +#include <tqimage.h> #include <stdlib.h> #include "events.h" -#include "vnctypes.h" + +extern "C" { +#include <rfb/rfbclient.h> +} class KVncView; @@ -57,68 +62,51 @@ struct InputEvent { } e; }; +class ControllerThreadObject : public TQObject { + Q_OBJECT -class WriterThread : public TQThread { -private: - TQMutex m_lock; - TQWaitCondition m_waiter; - volatile bool &m_quitFlag; - KVncView *m_view; + public: + ControllerThreadObject(KVncView *v, volatile bool &quitFlag); + ~ControllerThreadObject(); - TQTime m_lastIncrUpdate; // start()ed when a incr update is sent - bool m_lastIncrUpdatePostponed; + enum RemoteViewStatus status(); - // all things that can be send follow: - bool m_incrementalUpdateRQ; // for sending an incremental request - bool m_incrementalUpdateAnnounced; // set when a RQ will come soon - TQRegion m_updateRegionRQ; // for sending updates, null if it is done - TQValueList<InputEvent> m_inputEvents; // list of unsent input events - MouseEvent m_lastMouseEvent; - int m_mouseEventNum, m_keyEventNum; - TQString m_clientCut; + void setImage(const TQImage &img); + const TQImage image(int x = 0, int y = 0, int w = 0, int h = 0); + void authenticationResults(int resultCode); + void networkStatus(int statusCode); - void sendFatalError(ErrorCode s); + void setScaling(int w, int h); + void queueDrawRegion(int x, int y, int w, int h); -public: - WriterThread(KVncView *v, volatile bool &quitFlag); + rfbClient *cl; - void queueIncrementalUpdateRequest(); - void announceIncrementalUpdateRequest(); - void queueUpdateRequest(const TQRegion &r); - void queueMouseEvent(int x, int y, int buttonMask); - void queueKeyEvent(unsigned int k, bool down); - void queueClientCut(const TQString &text); - void kick(); + public slots: + void run(); -protected: - void run(); - bool sendIncrementalUpdateRequest(); - bool sendUpdateRequest(const TQRegion &r); - bool sendInputEvents(const TQValueList<InputEvent> &events); -}; - - - -class ControllerThread : public TQThread { -private: - KVncView *m_view; - enum RemoteViewStatus m_status; - WriterThread &m_wthread; - volatile bool &m_quitFlag; - volatile bool m_desktopInitialized; - TQWaitCondition m_waiter; - - void changeStatus(RemoteViewStatus s); - void sendFatalError(ErrorCode s); - -public: - ControllerThread(KVncView *v, WriterThread &wt, volatile bool &quitFlag); - enum RemoteViewStatus status(); - void desktopInit(); - void kick(); - -protected: - void run(); + public: + void queueMouseEvent(int x, int y, int buttonMask); + void queueKeyEvent(unsigned int k, bool down); + void queueClientCut(const TQString &text); + + private: + KVncView *m_view; + TQImage m_image; + TQImage m_scaledImage; + TQMutex mutex; + enum RemoteViewStatus m_status; + volatile bool &m_quitFlag; + + bool m_scaling; + int m_scalingWidth; + int m_scalingHeight; + bool m_resizeEntireFrame; + + // all things that can be send follow: + TQValueList<InputEvent> m_inputEvents; // list of unsent input events + + void changeStatus(RemoteViewStatus s); + void sendFatalError(ErrorCode s); }; diff --git a/krdc/vnc/tight.c b/krdc/vnc/tight.c deleted file mode 100644 index 597dad6c..00000000 --- a/krdc/vnc/tight.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -/* - * tight.c - handle ``tight'' encoding. - * - * This file shouldn't be compiled directly. It is included multiple - * times by rfbproto.c, each time with a different definition of the - * macro BPP. For each value of BPP, this file defines a function - * which handles a tight-encoded rectangle with BPP bits per pixel. - * - */ - -#define TIGHT_MIN_TO_COMPRESS 12 - -#define CARDBPP CONCAT2E(CARD,BPP) -#define filterPtrBPP CONCAT2E(filterPtr,BPP) - -#define HandleTightBPP CONCAT2E(HandleTight,BPP) -#define InitFilterCopyBPP CONCAT2E(InitFilterCopy,BPP) -#define InitFilterPaletteBPP CONCAT2E(InitFilterPalette,BPP) -#define InitFilterGradientBPP CONCAT2E(InitFilterGradient,BPP) -#define FilterCopyBPP CONCAT2E(FilterCopy,BPP) -#define FilterPaletteBPP CONCAT2E(FilterPalette,BPP) -#define FilterGradientBPP CONCAT2E(FilterGradient,BPP) -#define FillRectangleBPP CONCAT2E(FillRectangle,BPP) - -#if BPP != 8 -#define DecompressJpegRectBPP CONCAT2E(DecompressJpegRect,BPP) -#endif - -#ifndef RGB_TO_PIXEL - -#define RGB_TO_PIXEL(bpp,r,g,b) \ - (((CARD##bpp)(r) & myFormat.redMax) << myFormat.redShift | \ - ((CARD##bpp)(g) & myFormat.greenMax) << myFormat.greenShift | \ - ((CARD##bpp)(b) & myFormat.blueMax) << myFormat.blueShift) - -#define RGB24_TO_PIXEL(bpp,r,g,b) \ - ((((CARD##bpp)(r) & 0xFF) * myFormat.redMax + 127) / 255 \ - << myFormat.redShift | \ - (((CARD##bpp)(g) & 0xFF) * myFormat.greenMax + 127) / 255 \ - << myFormat.greenShift | \ - (((CARD##bpp)(b) & 0xFF) * myFormat.blueMax + 127) / 255 \ - << myFormat.blueShift) - -#define RGB24_TO_PIXEL32(r,g,b) \ - (((CARD32)(r) & 0xFF) << myFormat.redShift | \ - ((CARD32)(g) & 0xFF) << myFormat.greenShift | \ - ((CARD32)(b) & 0xFF) << myFormat.blueShift) - -#endif - -/* Type declarations */ - -typedef void (*filterPtrBPP)(int, CARDBPP *); - -/* Prototypes */ - -static int InitFilterCopyBPP (int rw, int rh); -static int InitFilterPaletteBPP (int rw, int rh); -static int InitFilterGradientBPP (int rw, int rh); -static void FilterCopyBPP (int numRows, CARDBPP *destBuffer); -static void FilterPaletteBPP (int numRows, CARDBPP *destBuffer); -static void FilterGradientBPP (int numRows, CARDBPP *destBuffer); - -static Bool DecompressJpegRectBPP(int x, int y, int w, int h); - -/* Definitions */ - -static Bool -HandleTightBPP (int rx, int ry, int rw, int rh) -{ - CARDBPP fill_colour; - XGCValues gcv; - CARD8 comp_ctl; - CARD8 filter_id; - filterPtrBPP filterFn; - z_streamp zs; - char *buffer2; - int err, stream_id, compressedLen, bitsPixel; - int bufferSize, rowSize, numRows, portionLen, rowsProcessed, extraBytes; - CARDBPP *rawData; - - if (!ReadFromRFBServer((char *)&comp_ctl, 1)) - return False; - - /* Flush zlib streams if we are told by the server to do so. */ - for (stream_id = 0; stream_id < 4; stream_id++) { - if ((comp_ctl & 1) && zlibStreamActive[stream_id]) { - if (inflateEnd (&zlibStream[stream_id]) != Z_OK && - zlibStream[stream_id].msg != NULL) - fprintf(stderr, "inflateEnd: %s\n", zlibStream[stream_id].msg); - zlibStreamActive[stream_id] = False; - } - comp_ctl >>= 1; - } - - /* Handle solid rectangles. */ - if (comp_ctl == rfbTightFill) { -#if BPP == 32 - if (myFormat.depth == 24 && myFormat.redMax == 0xFF && - myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) { - if (!ReadFromRFBServer(buffer, 3)) - return False; - fill_colour = RGB24_TO_PIXEL32(buffer[0], buffer[1], buffer[2]); - } else { - if (!ReadFromRFBServer((char*)&fill_colour, sizeof(fill_colour))) - return False; - } -#else - if (!ReadFromRFBServer((char*)&fill_colour, sizeof(fill_colour))) - return False; -#endif - - LockFramebuffer(); - FillRectangleBPP(fill_colour, rx, ry, rw, rh); - UnlockFramebuffer(); - SyncScreenRegion(rx, ry, rw, rh); - return True; - } - -#if BPP == 8 - if (comp_ctl == rfbTightJpeg) { - fprintf(stderr, "Tight encoding: JPEG is not supported in 8 bpp mode.\n"); - return False; - } -#else - if (comp_ctl == rfbTightJpeg) { - return DecompressJpegRectBPP(rx, ry, rw, rh); - } -#endif - - /* Quit on unsupported subencoding value. */ - if (comp_ctl > rfbTightMaxSubencoding) { - fprintf(stderr, "Tight encoding: bad subencoding value received.\n"); - return False; - } - - /* - * Here primary compression mode handling begins. - * Data was processed with optional filter + zlib compression. - */ - - /* First, we should identify a filter to use. */ - if ((comp_ctl & rfbTightExplicitFilter) != 0) { - if (!ReadFromRFBServer((char*)&filter_id, 1)) - return False; - - switch (filter_id) { - case rfbTightFilterCopy: - filterFn = FilterCopyBPP; - bitsPixel = InitFilterCopyBPP(rw, rh); - break; - case rfbTightFilterPalette: - filterFn = FilterPaletteBPP; - bitsPixel = InitFilterPaletteBPP(rw, rh); - break; - case rfbTightFilterGradient: - filterFn = FilterGradientBPP; - bitsPixel = InitFilterGradientBPP(rw, rh); - break; - default: - fprintf(stderr, "Tight encoding: unknown filter code received.\n"); - return False; - } - } else { - filterFn = FilterCopyBPP; - bitsPixel = InitFilterCopyBPP(rw, rh); - } - if (bitsPixel == 0) { - fprintf(stderr, "Tight encoding: error receiving palette.\n"); - return False; - } - - /* Determine if the data should be decompressed or just copied. */ - rowSize = (rw * bitsPixel + 7) / 8; - if (rh * rowSize < TIGHT_MIN_TO_COMPRESS) { - if (!ReadFromRFBServer((char*)buffer, rh * rowSize)) - return False; - - buffer2 = &buffer[TIGHT_MIN_TO_COMPRESS * 4]; - filterFn(rh, (CARDBPP *)buffer2); - CopyDataToScreen(buffer2, rx, ry, rw, rh); - - return True; - } - - /* Read the length (1..3 bytes) of compressed data following. */ - compressedLen = (int)ReadCompactLen(); - if (compressedLen <= 0) { - fprintf(stderr, "Incorrect data received from the server.\n"); - return False; - } - - /* Now let's initialize compression stream if needed. */ - stream_id = comp_ctl & 0x03; - zs = &zlibStream[stream_id]; - if (!zlibStreamActive[stream_id]) { - zs->zalloc = Z_NULL; - zs->zfree = Z_NULL; - zs->opaque = Z_NULL; - err = inflateInit(zs); - if (err != Z_OK) { - if (zs->msg != NULL) - fprintf(stderr, "InflateInit error: %s.\n", zs->msg); - return False; - } - zlibStreamActive[stream_id] = True; - } - - /* Read, decode and draw actual pixel data in a loop. */ - - bufferSize = BUFFER_SIZE * bitsPixel / (bitsPixel + BPP) & 0xFFFFFFFC; - buffer2 = &buffer[bufferSize]; - if (rowSize > bufferSize) { - /* Should be impossible when BUFFER_SIZE >= 16384 */ - fprintf(stderr, "Internal error: incorrect buffer size.\n"); - return False; - } - - rowsProcessed = 0; - extraBytes = 0; - - while (compressedLen > 0) { - if (compressedLen > ZLIB_BUFFER_SIZE) - portionLen = ZLIB_BUFFER_SIZE; - else - portionLen = compressedLen; - - if (!ReadFromRFBServer((char*)zlib_buffer, portionLen)) - return False; - - compressedLen -= portionLen; - - zs->next_in = (Bytef *)zlib_buffer; - zs->avail_in = portionLen; - - do { - zs->next_out = (Bytef *)&buffer[extraBytes]; - zs->avail_out = bufferSize - extraBytes; - - err = inflate(zs, Z_SYNC_FLUSH); - if (err == Z_BUF_ERROR) /* Input exhausted -- no problem. */ - break; - if (err != Z_OK && err != Z_STREAM_END) { - if (zs->msg != NULL) { - fprintf(stderr, "Inflate error: %s.\n", zs->msg); - } else { - fprintf(stderr, "Inflate error: %d.\n", err); - } - return False; - } - - numRows = (bufferSize - zs->avail_out) / rowSize; - - filterFn(numRows, (CARDBPP *)buffer2); - - extraBytes = bufferSize - zs->avail_out - numRows * rowSize; - if (extraBytes > 0) - memcpy(buffer, &buffer[numRows * rowSize], extraBytes); - - CopyDataToScreen(buffer2, rx, ry + rowsProcessed, rw, numRows); - rowsProcessed += numRows; - } - while (zs->avail_out == 0); - } - - if (rowsProcessed != rh) { - fprintf(stderr, "Incorrect number of scan lines after decompression.\n"); - return False; - } - - return True; -} - -/*---------------------------------------------------------------------------- - * - * Filter stuff. - * - */ - -/* - The following variables are defined in rfbproto.c: - static Bool cutZeros; - static int rectWidth, rectColors; - static CARD8 tightPalette[256*4]; - static CARD8 tightPrevRow[2048*3*sizeof(CARD16)]; -*/ - -static int -InitFilterCopyBPP (int rw, int rh) -{ - rectWidth = rw; - -#if BPP == 32 - if (myFormat.depth == 24 && myFormat.redMax == 0xFF && - myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) { - cutZeros = True; - return 24; - } else { - cutZeros = False; - } -#endif - - return BPP; -} - -static void -FilterCopyBPP (int numRows, CARDBPP *dst) -{ - -#if BPP == 32 - int x, y; - - if (cutZeros) { - for (y = 0; y < numRows; y++) { - for (x = 0; x < rectWidth; x++) { - dst[y*rectWidth+x] = - RGB24_TO_PIXEL32(buffer[(y*rectWidth+x)*3], - buffer[(y*rectWidth+x)*3+1], - buffer[(y*rectWidth+x)*3+2]); - } - } - return; - } -#endif - - memcpy (dst, buffer, numRows * rectWidth * (BPP / 8)); -} - -static int -InitFilterGradientBPP (int rw, int rh) -{ - int bits; - - bits = InitFilterCopyBPP(rw, rh); - if (cutZeros) - memset(tightPrevRow, 0, rw * 3); - else - memset(tightPrevRow, 0, rw * 3 * sizeof(CARD16)); - - return bits; -} - -#if BPP == 32 - -static void -FilterGradient24 (int numRows, CARD32 *dst) -{ - int x, y, c; - CARD8 thisRow[2048*3]; - CARD8 pix[3]; - int est[3]; - - for (y = 0; y < numRows; y++) { - - /* First pixel in a row */ - for (c = 0; c < 3; c++) { - pix[c] = tightPrevRow[c] + buffer[y*rectWidth*3+c]; - thisRow[c] = pix[c]; - } - dst[y*rectWidth] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); - - /* Remaining pixels of a row */ - for (x = 1; x < rectWidth; x++) { - for (c = 0; c < 3; c++) { - est[c] = (int)tightPrevRow[x*3+c] + (int)pix[c] - - (int)tightPrevRow[(x-1)*3+c]; - if (est[c] > 0xFF) { - est[c] = 0xFF; - } else if (est[c] < 0x00) { - est[c] = 0x00; - } - pix[c] = (CARD8)est[c] + buffer[(y*rectWidth+x)*3+c]; - thisRow[x*3+c] = pix[c]; - } - dst[y*rectWidth+x] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); - } - - memcpy(tightPrevRow, thisRow, rectWidth * 3); - } -} - -#endif - -static void -FilterGradientBPP (int numRows, CARDBPP *dst) -{ - int x, y, c; - CARDBPP *src = (CARDBPP *)buffer; - CARD16 *thatRow = (CARD16 *)tightPrevRow; - CARD16 thisRow[2048*3]; - CARD16 pix[3]; - CARD16 max[3]; - int shift[3]; - int est[3]; - -#if BPP == 32 - if (cutZeros) { - FilterGradient24(numRows, dst); - return; - } -#endif - - max[0] = myFormat.redMax; - max[1] = myFormat.greenMax; - max[2] = myFormat.blueMax; - - shift[0] = myFormat.redShift; - shift[1] = myFormat.greenShift; - shift[2] = myFormat.blueShift; - - for (y = 0; y < numRows; y++) { - - /* First pixel in a row */ - for (c = 0; c < 3; c++) { - pix[c] = (CARD16)((src[y*rectWidth] >> shift[c]) + thatRow[c] & max[c]); - thisRow[c] = pix[c]; - } - dst[y*rectWidth] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); - - /* Remaining pixels of a row */ - for (x = 1; x < rectWidth; x++) { - for (c = 0; c < 3; c++) { - est[c] = (int)thatRow[x*3+c] + (int)pix[c] - (int)thatRow[(x-1)*3+c]; - if (est[c] > (int)max[c]) { - est[c] = (int)max[c]; - } else if (est[c] < 0) { - est[c] = 0; - } - pix[c] = (CARD16)((src[y*rectWidth+x] >> shift[c]) + est[c] & max[c]); - thisRow[x*3+c] = pix[c]; - } - dst[y*rectWidth+x] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); - } - memcpy(thatRow, thisRow, rectWidth * 3 * sizeof(CARD16)); - } -} - -static int -InitFilterPaletteBPP (int rw, int rh) -{ - int i; - CARD8 numColors; - CARDBPP *palette = (CARDBPP *)tightPalette; - - rectWidth = rw; - - if (!ReadFromRFBServer((char*)&numColors, 1)) - return 0; - - rectColors = (int)numColors; - if (++rectColors < 2) - return 0; - -#if BPP == 32 - if (myFormat.depth == 24 && myFormat.redMax == 0xFF && - myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) { - if (!ReadFromRFBServer((char*)&tightPalette, rectColors * 3)) - return 0; - for (i = rectColors - 1; i >= 0; i--) { - palette[i] = RGB24_TO_PIXEL32(tightPalette[i*3], - tightPalette[i*3+1], - tightPalette[i*3+2]); - } - return (rectColors == 2) ? 1 : 8; - } -#endif - - if (!ReadFromRFBServer((char*)&tightPalette, rectColors * (BPP / 8))) - return 0; - - return (rectColors == 2) ? 1 : 8; -} - -static void -FilterPaletteBPP (int numRows, CARDBPP *dst) -{ - int x, y, b, w; - CARD8 *src = (CARD8 *)buffer; - CARDBPP *palette = (CARDBPP *)tightPalette; - - if (rectColors == 2) { - w = (rectWidth + 7) / 8; - for (y = 0; y < numRows; y++) { - for (x = 0; x < rectWidth / 8; x++) { - for (b = 7; b >= 0; b--) - dst[y*rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1]; - } - for (b = 7; b >= 8 - rectWidth % 8; b--) { - dst[y*rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1]; - } - } - } else { - for (y = 0; y < numRows; y++) - for (x = 0; x < rectWidth; x++) - dst[y*rectWidth+x] = palette[(int)src[y*rectWidth+x]]; - } -} - -#if BPP != 8 - -/*---------------------------------------------------------------------------- - * - * JPEG decompression. - * - */ - -/* - The following variables are defined in rfbproto.c: - static Bool jpegError; - static struct jpeg_source_mgr jpegSrcManager; - static JOCTET *jpegBufferPtr; - static size_t *jpegBufferLen; -*/ - -static Bool -DecompressJpegRectBPP(int x, int y, int w, int h) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - int compressedLen; - CARD8 *compressedData; - CARDBPP *pixelPtr; - JSAMPROW rowPointer[1]; - int dx, dy; - - compressedLen = (int)ReadCompactLen(); - if (compressedLen <= 0) { - fprintf(stderr, "Incorrect data received from the server.\n"); - return False; - } - - if (compressedLen > MAX_JPEG_SIZE) { - fprintf(stderr, "To large data announced by the server.\n"); - return False; - } - - compressedData = malloc(compressedLen); - if (compressedData == NULL) { - fprintf(stderr, "Memory allocation error.\n"); - return False; - } - - if (!ReadFromRFBServer((char*)compressedData, compressedLen)) { - free(compressedData); - return False; - } - - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); - - JpegSetSrcManager(&cinfo, compressedData, compressedLen); - - jpeg_read_header(&cinfo, TRUE); - cinfo.out_color_space = JCS_RGB; - - jpeg_start_decompress(&cinfo); - if (cinfo.output_width != w || cinfo.output_height != h || - cinfo.output_components != 3) { - fprintf(stderr, "Tight Encoding: Wrong JPEG data received.\n"); - jpeg_destroy_decompress(&cinfo); - free(compressedData); - return False; - } - - rowPointer[0] = (JSAMPROW)buffer; - dy = 0; - while (cinfo.output_scanline < cinfo.output_height) { - jpeg_read_scanlines(&cinfo, rowPointer, 1); - if (jpegError) { - break; - } - pixelPtr = (CARDBPP *)&buffer[BUFFER_SIZE / 2]; - for (dx = 0; dx < w; dx++) { - *pixelPtr++ = - RGB24_TO_PIXEL(BPP, buffer[dx*3], buffer[dx*3+1], buffer[dx*3+2]); - } - CopyDataToScreen(&buffer[BUFFER_SIZE / 2], x, y + dy, w, 1); - dy++; - } - - if (!jpegError) - jpeg_finish_decompress(&cinfo); - - jpeg_destroy_decompress(&cinfo); - free(compressedData); - - return !jpegError; -} - -#endif - diff --git a/krdc/vnc/vncauth.c b/krdc/vnc/vncauth.c deleted file mode 100644 index f1e2880c..00000000 --- a/krdc/vnc/vncauth.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -/* - * vncauth.c - Functions for VNC password management and authentication. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#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. 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); - - srandom(seed); - for (i = 0; i < CHALLENGESIZE; i++) { - bytes[i] = (unsigned char)(random() & 255); - } -} - - -/* - * Encrypt CHALLENGESIZE bytes in memory using a password. - */ - -void -vncEncryptBytes(unsigned char *bytes, char *passwd) -{ - unsigned char key[8]; - int i; - - /* key is simply password padded with nulls */ - - for (i = 0; i < 8; i++) { - if (i < strlen(passwd)) { - key[i] = passwd[i]; - } else { - key[i] = 0; - } - } - - deskey(key, EN0); - - for (i = 0; i < CHALLENGESIZE; i += 8) { - des(bytes+i, bytes+i); - } -} diff --git a/krdc/vnc/vncauth.h b/krdc/vnc/vncauth.h deleted file mode 100644 index 044a3db0..00000000 --- a/krdc/vnc/vncauth.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * 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/krdc/vnc/vnctypes.h b/krdc/vnc/vnctypes.h deleted file mode 100644 index fae12549..00000000 --- a/krdc/vnc/vnctypes.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2002 Tim Jansen. All Rights Reserved. - * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. - * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. - * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -#ifndef VNCTYPES_H -#define VNCTYPES_H - -#if(defined __cplusplus) -extern "C" -{ -#endif - -#include <X11/Xmd.h> - - -typedef struct { - int shareDesktop; /* bool */ - int viewOnly; /* bool */ - - const char* encodingsString; - - int useBGR233; /* bool */ - int nColours; - int useSharedColours; /* bool */ - int requestedDepth; - - int rawDelay; - int copyRectDelay; - - int debug; /* bool */ - - int compressLevel; - int qualityLevel; - int dotCursor; /* bool */ - -} AppData; - - -enum InitStatus { - INIT_OK = 0, - INIT_NAME_RESOLUTION_FAILURE = 1, - INIT_PROTOCOL_FAILURE = 2, - INIT_CONNECTION_FAILED = 3, - INIT_AUTHENTICATION_FAILED = 4, - INIT_NO_SERVER = 5, - INIT_SERVER_BLOCKED = 6, - INIT_ABORTED = 7 -}; - - -#if(defined __cplusplus) -} -#endif - -#endif diff --git a/krdc/vnc/vncviewer.h b/krdc/vnc/vncviewer.h index 285357b9..02e3c635 100644 --- a/krdc/vnc/vncviewer.h +++ b/krdc/vnc/vncviewer.h @@ -36,28 +36,14 @@ #include <X11/keysym.h> #include <X11/Xatom.h> #include <X11/Xmu/StdSel.h> -#include "vnctypes.h" #if(defined __cplusplus) extern "C" { #endif -#include "rfbproto.h" - -extern int endianTest; - -#define Swap16IfLE(s) \ - (*(char *)&endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s)) - -#define Swap32IfLE(l) \ - (*(char *)&endianTest ? ((((l) & 0xff000000) >> 24) | \ - (((l) & 0x00ff0000) >> 8) | \ - (((l) & 0x0000ff00) << 8) | \ - (((l) & 0x000000ff) << 24)) : (l)) - -#define MAX_ENCODINGS 20 - +#include "rfb/rfbclient.h" +#include "rfb/rfbproto.h" /** kvncview.cpp **/ @@ -78,108 +64,6 @@ extern void beep(); extern void newServerCut(char *bytes, int len); extern void postMouseEvent(int x, int y, int buttonMask); -/** threads.cpp **/ - -extern void queueIncrementalUpdateRequest(); -extern void announceIncrementalUpdateRequest(); - -/* colour.c */ - -extern unsigned long BGR233ToPixel[]; - -extern Colormap cmap; -extern Visual *vis; -extern unsigned int visdepth, visbpp; - -extern void SetVisualAndCmap(void); - -/* desktop.c */ - -extern Widget form, viewport, desktop; -extern GC gc; -extern GC srcGC, dstGC; -extern Dimension dpyWidth, dpyHeight; - -extern void DesktopInit(Window win); -extern void ToplevelInit(void); -extern void SendRFBEvent(XEvent *event, String *params, Cardinal *num_params); -extern void CopyDataToScreen(char *buf, int x, int y, int width, int height); -extern void CopyDataFromScreen(char *buf, int x, int y, int width, int height); -extern void FillRectangle8(CARD8, int x, int y, int width, int height); -extern void FillRectangle16(CARD16, int x, int y, int width, int height); -extern void FillRectangle32(CARD32, int x, int y, int width, int height); -extern void CopyArea(int srcX, int srcY, int width, int height, int x, int y); -extern void SyncScreenRegion(int x, int y, int width, int height); -extern void SyncScreenRegionX11Thread(int x, int y, int width, int height); -extern void drawCursor(void); -extern void DrawCursorX11Thread(int x, int y); -extern void undrawCursor(void); -extern void getBoundingRectCursor(int cx, int cy, int _imageIndex, - int *x, int *y, int *w, int *h); -extern int rectsIntersect(int x, int y, int w, int h, - int x2, int y2, int w2, int h2); -extern int rectContains(int outX, int outY, int outW, int outH, - int inX, int inY, int inW, int inH); -extern void rectsJoin(int *nx1, int *ny1, int *nw1, int *nh1, - int x2, int y2, int w2, int h2); -extern void DrawZoomedScreenRegionX11Thread(Window win, int zwidth, - int zheight, - int x, int y, - int width, int height); -extern void DrawScreenRegionX11Thread(Window win, int x, int y, - int width, int height); -extern void Cleanup(void); -extern XImage *CreateShmZoomImage(void); -extern XImage *CreateShmImage(void); -extern void ShmCleanup(void); -extern void freeDesktopResources(void); - -/* rfbproto.c */ - -extern int rfbsock; -extern Bool canUseCoRRE; -extern Bool canUseHextile; -extern char *desktopName; -extern rfbPixelFormat myFormat; -extern rfbServerInitMsg si; - -extern int cursorX, cursorY; -extern int imageIndex; -typedef struct { - int set; - int w, h; - int hotX, hotY; - int len; - char *image; -} PointerImage; -extern PointerImage pointerImages[]; - -extern int ConnectToRFBServer(const char *hostname, int port); -extern enum InitStatus InitialiseRFBConnection(void); -extern Bool SetFormatAndEncodings(void); -extern Bool SendIncrementalFramebufferUpdateRequest(void); -extern Bool SendFramebufferUpdateRequest(int x, int y, int w, int h, - Bool incremental); -extern Bool SendPointerEvent(int x, int y, int buttonMask); -extern Bool SendKeyEvent(CARD32 key, Bool down); -extern Bool SendClientCutText(const char *str, int len); -extern Bool HandleRFBServerMessage(void); - -extern void PrintPixelFormat(rfbPixelFormat *format); -extern void freeRFBProtoResources(void); -extern void freeResources(void); - -/* sockets.c */ - -extern Bool errorMessageOnReadFailure; - -extern Bool ReadFromRFBServer(char *out, unsigned int n); -extern Bool WriteExact(int sock, const char *buf, int n); -extern int ConnectToTcpAddr(unsigned int host, int port); - -extern int StringToIPAddr(const char *str, unsigned int *addr); -extern void freeSocketsResources(void); - #if(defined __cplusplus) } #endif diff --git a/krdc/vnc/zlib.c b/krdc/vnc/zlib.c deleted file mode 100644 index 21767b3f..00000000 --- a/krdc/vnc/zlib.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. - * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -/* - * zlib.c - handle zlib encoding. - * - * This file shouldn't be compiled directly. It is included multiple times by - * rfbproto.c, each time with a different definition of the macro BPP. For - * each value of BPP, this file defines a function which handles an zlib - * encoded rectangle with BPP bits per pixel. - */ - -#define HandleZlibBPP CONCAT2E(HandleZlib,BPP) -#define CARDBPP CONCAT2E(CARD,BPP) - -static Bool -HandleZlibBPP (int rx, int ry, int rw, int rh) -{ - rfbZlibHeader hdr; - int remaining; - int inflateResult; - int toRead; - - /* First make sure we have a large enough raw buffer to hold the - * decompressed data. In practice, with a fixed BPP, fixed frame - * buffer size and the first update containing the entire frame - * buffer, this buffer allocation should only happen once, on the - * first update. - */ - if ( raw_buffer_size < (( rw * rh ) * ( BPP / 8 ))) { - - if ( raw_buffer != NULL ) { - - free( raw_buffer ); - - } - - raw_buffer_size = (( rw * rh ) * ( BPP / 8 )); - raw_buffer = (char*) malloc( raw_buffer_size ); - - } - - if (!ReadFromRFBServer((char *)&hdr, sz_rfbZlibHeader)) - return False; - - remaining = Swap32IfLE(hdr.nBytes); - - /* Need to initialize the decompressor state. */ - decompStream.next_in = ( Bytef * )buffer; - decompStream.avail_in = 0; - decompStream.next_out = ( Bytef * )raw_buffer; - decompStream.avail_out = raw_buffer_size; - decompStream.data_type = Z_BINARY; - - /* Initialize the decompression stream structures on the first invocation. */ - if ( decompStreamInited == False ) { - - inflateResult = inflateInit( &decompStream ); - - if ( inflateResult != Z_OK ) { - fprintf(stderr, - "inflateInit returned error: %d, msg: %s\n", - inflateResult, - decompStream.msg); - return False; - } - - decompStreamInited = True; - - } - - inflateResult = Z_OK; - - /* Process buffer full of data until no more to process, or - * some type of inflater error, or Z_STREAM_END. - */ - while (( remaining > 0 ) && - ( inflateResult == Z_OK )) { - - if ( remaining > BUFFER_SIZE ) { - toRead = BUFFER_SIZE; - } - else { - toRead = remaining; - } - - /* Fill the buffer, obtaining data from the server. */ - if (!ReadFromRFBServer(buffer,toRead)) - return False; - - decompStream.next_in = ( Bytef * )buffer; - decompStream.avail_in = toRead; - - /* Need to uncompress buffer full. */ - inflateResult = inflate( &decompStream, Z_SYNC_FLUSH ); - - /* We never supply a dictionary for compression. */ - if ( inflateResult == Z_NEED_DICT ) { - fprintf(stderr,"zlib inflate needs a dictionary!\n"); - return False; - } - if ( inflateResult < 0 ) { - fprintf(stderr, - "zlib inflate returned error: %d, msg: %s\n", - inflateResult, - decompStream.msg); - return False; - } - - /* Result buffer allocated to be at least large enough. We should - * never run out of space! - */ - if (( decompStream.avail_in > 0 ) && - ( decompStream.avail_out <= 0 )) { - fprintf(stderr,"zlib inflate ran out of space!\n"); - return False; - } - - remaining -= toRead; - - } /* while ( remaining > 0 ) */ - - if ( inflateResult == Z_OK ) { - - /* Put the uncompressed contents of the update on the screen. */ - CopyDataToScreen(raw_buffer, rx, ry, rw, rh); - - } - else { - - fprintf(stderr, - "zlib inflate returned error: %d, msg: %s\n", - inflateResult, - decompStream.msg); - return False; - - } - - return True; -} |