*** Xvnc/programs/Xserver/hw/vnc/auth.c 1999/11/06 01:12:31 1.1 --- Xvnc/programs/Xserver/hw/vnc/auth.c 1999/11/06 01:19:01 *************** *** 62,68 **** cl->state = RFB_INITIALISATION; } ! if (WriteExact(cl->sock, buf, len) < 0) { rfbLogPerror("rfbAuthNewClient: write"); rfbCloseSock(cl->sock); return; --- 62,68 ---- cl->state = RFB_INITIALISATION; } ! if (ZWriteExact(cl, buf, len) < 0) { rfbLogPerror("rfbAuthNewClient: write"); rfbCloseSock(cl->sock); return; *************** *** 100,106 **** authResult = Swap32IfLE(rfbVncAuthFailed); ! if (WriteExact(cl->sock, (char *)&authResult, 4) < 0) { rfbLogPerror("rfbAuthProcessClientMessage: write"); } rfbCloseSock(cl->sock); --- 100,106 ---- authResult = Swap32IfLE(rfbVncAuthFailed); ! if (ZWriteExact(cl, (char *)&authResult, 4) < 0) { rfbLogPerror("rfbAuthProcessClientMessage: write"); } rfbCloseSock(cl->sock); *************** *** 122,128 **** authResult = Swap32IfLE(rfbVncAuthFailed); ! if (WriteExact(cl->sock, (char *)&authResult, 4) < 0) { rfbLogPerror("rfbAuthProcessClientMessage: write"); } rfbCloseSock(cl->sock); --- 122,128 ---- authResult = Swap32IfLE(rfbVncAuthFailed); ! if (ZWriteExact(cl, (char *)&authResult, 4) < 0) { rfbLogPerror("rfbAuthProcessClientMessage: write"); } rfbCloseSock(cl->sock); *************** *** 131,137 **** authResult = Swap32IfLE(rfbVncAuthOK); ! if (WriteExact(cl->sock, (char *)&authResult, 4) < 0) { rfbLogPerror("rfbAuthProcessClientMessage: write"); rfbCloseSock(cl->sock); return; --- 131,137 ---- authResult = Swap32IfLE(rfbVncAuthOK); ! if (ZWriteExact(cl, (char *)&authResult, 4) < 0) { rfbLogPerror("rfbAuthProcessClientMessage: write"); rfbCloseSock(cl->sock); return; *** Xvnc/programs/Xserver/hw/vnc/rfb.h 1999/11/05 22:20:05 1.1 --- Xvnc/programs/Xserver/hw/vnc/rfb.h 1999/11/06 02:22:31 *************** *** 27,32 **** --- 27,33 ---- #include "osdep.h" #include #include + #include "../../../../lib/zlib/zlib.h" #define MAX_ENCODINGS 10 *************** *** 132,137 **** --- 133,142 ---- RFB_NORMAL /* normal protocol messages */ } state; + z_streamp Zstream; /* Pointer to data structure used for */ + /* zlib compression of server output */ + Bool useCompression; /* If true, do compression in ZWriteExact */ + Bool reverseConnection; Bool readyForSetColourMapEntries; *************** *** 296,301 **** --- 301,307 ---- extern int ReadExact(int sock, char *buf, int len); extern int WriteExact(int sock, char *buf, int len); + extern int ZWriteExact(rfbClientPtr cl, char *buf, int len); extern int ListenOnTCPPort(int port); extern int ListenOnUDPPort(int port); extern int ConnectToTcpAddr(char *host, int port); *** Xvnc/programs/Xserver/hw/vnc/rfbserver.c 1999/11/05 06:27:02 1.1 --- Xvnc/programs/Xserver/hw/vnc/rfbserver.c 1999/11/06 05:48:38 *************** *** 138,143 **** --- 138,145 ---- cl->state = RFB_PROTOCOL_VERSION; + cl->useCompression = FALSE; + cl->Zstream=NULL; cl->reverseConnection = FALSE; cl->readyForSetColourMapEntries = FALSE; cl->useCopyRect = FALSE; *************** *** 218,223 **** --- 220,227 ---- REGION_UNINIT(pScreen,&cl->modifiedRegion); rfbPrintStats(cl); + if (cl->useCompression==TRUE) rfbPrintZStats(cl); + if (cl->Zstream!=NULL) deflateEnd(cl->Zstream); if (cl->translateLookupTable) free(cl->translateLookupTable); *************** *** 438,443 **** --- 442,448 ---- { int n; rfbClientToServerMsg msg; + rfbServerToClientMsg servmsg; char *str; if ((n = ReadExact(cl->sock, (char *)&msg, 1)) <= 0) { *************** *** 449,454 **** --- 454,491 ---- switch (msg.type) { + case rfbClientWantsZlibs: + + if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, + sz_rfbClientWantsZlibsMsg - 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseSock(cl->sock); + return; + } + rfbLog("Client wants zlib level %d\n", msg.wantz.level); + + /* Create the z_stream data structure required */ + cl->Zstream= (z_streamp)malloc(sizeof(z_stream)); + if (cl->Zstream==NULL) break; /* Failure, so no compression */ + + /* Initialise the z_stream data structure */ + cl->Zstream->zalloc= (alloc_func)Z_NULL; + cl->Zstream->zfree= (free_func)Z_NULL; + cl->Zstream->opaque= (void *)Z_NULL; + + if (deflateInit(cl->Zstream, msg.wantz.level)!=Z_OK) + break; /* Failure in making stream, so no compression */ + + /* Inform the client that compression is now on */ + servmsg.type= rfbServerZlibsOn; + if (WriteExact(cl->sock, (char *)&servmsg, sz_rfbServerZlibsMsg) < 0) { + rfbLogPerror("rfbServerZlibsOn: write"); + rfbCloseSock(cl->sock); + } + cl->useCompression = TRUE; /* Turn on AFTER the reply! */ + return; + case rfbSetPixelFormat: if ((n = ReadExact(cl->sock, ((char *)&msg) + 1, *************** *** 1070,1076 **** fprintf(stderr,"\n"); */ ! if (WriteExact(cl->sock, updateBuf, ublen) < 0) { rfbLogPerror("rfbSendUpdateBuf: write"); rfbCloseSock(cl->sock); return FALSE; --- 1107,1113 ---- fprintf(stderr,"\n"); */ ! if (ZWriteExact(cl, updateBuf, ublen) < 0) { rfbLogPerror("rfbSendUpdateBuf: write"); rfbCloseSock(cl->sock); return FALSE; *************** *** 1122,1128 **** len += nColours * 3 * 2; ! if (WriteExact(cl->sock, buf, len) < 0) { rfbLogPerror("rfbSendSetColourMapEntries: write"); rfbCloseSock(cl->sock); return FALSE; --- 1159,1165 ---- len += nColours * 3 * 2; ! if (ZWriteExact(cl, buf, len) < 0) { rfbLogPerror("rfbSendSetColourMapEntries: write"); rfbCloseSock(cl->sock); return FALSE; *************** *** 1144,1150 **** for (cl = rfbClientHead; cl; cl = nextCl) { nextCl = cl->next; b.type = rfbBell; ! if (WriteExact(cl->sock, (char *)&b, sz_rfbBellMsg) < 0) { rfbLogPerror("rfbSendBell: write"); rfbCloseSock(cl->sock); } --- 1181,1187 ---- for (cl = rfbClientHead; cl; cl = nextCl) { nextCl = cl->next; b.type = rfbBell; ! if (ZWriteExact(cl, (char *)&b, sz_rfbBellMsg) < 0) { rfbLogPerror("rfbSendBell: write"); rfbCloseSock(cl->sock); } *************** *** 1166,1178 **** nextCl = cl->next; sct.type = rfbServerCutText; sct.length = Swap32IfLE(len); ! if (WriteExact(cl->sock, (char *)&sct, sz_rfbServerCutTextMsg) < 0) { rfbLogPerror("rfbSendServerCutText: write"); rfbCloseSock(cl->sock); continue; } ! if (WriteExact(cl->sock, str, len) < 0) { rfbLogPerror("rfbSendServerCutText: write"); rfbCloseSock(cl->sock); } --- 1203,1215 ---- nextCl = cl->next; sct.type = rfbServerCutText; sct.length = Swap32IfLE(len); ! if (ZWriteExact(cl, (char *)&sct, sz_rfbServerCutTextMsg) < 0) { rfbLogPerror("rfbSendServerCutText: write"); rfbCloseSock(cl->sock); continue; } ! if (ZWriteExact(cl, str, len) < 0) { rfbLogPerror("rfbSendServerCutText: write"); rfbCloseSock(cl->sock); } *** Xvnc/programs/Xserver/hw/vnc/sockets.c 1999/11/06 01:12:31 1.1 --- Xvnc/programs/Xserver/hw/vnc/sockets.c 1999/11/06 23:12:22 *************** *** 441,446 **** --- 441,504 ---- } + /* + * ZWriteExact compresses an exact number of bytes into Zstream. + * Returns 1 if those bytes have been compressed, or -1 if an error occurred + * (errno is set to * ETIMEDOUT if it timed out). + * + * Much of this code borrowed from ssh 1.x compress.c source + */ + + int ZWriteExact(rfbClientPtr cl, char *buf, int len) + { + int i,status; + char Zbuf[4096]; + + if (cl->useCompression == FALSE) return(WriteExact(cl->sock, buf, len)); + + if (len==0) return 1; /* Nothing to do! */ + + /* Set up the buffer to compress */ + cl->Zstream->next_in= (Bytef *)buf; + cl->Zstream->avail_in= len; + + /* Loop compressing until deflate() returns with avail_out != 0. */ + do { + /* Set up fixed-size output buffer. */ + cl->Zstream->next_out = (unsigned char *)Zbuf; + cl->Zstream->avail_out = sizeof(Zbuf); + + /* Compress as much data into the buffer as possible. */ + status = deflate(cl->Zstream, Z_SYNC_FLUSH); + switch (status) + { + case Z_OK: + /* Send the compressed buffer to the other end */ + i=WriteExact(cl->sock, Zbuf, sizeof(Zbuf) - cl->Zstream->avail_out); + if (i!=1) return(i); + break; + case Z_STREAM_END: + rfbLog("ZWriteExact: %s\n", "deflate returned Z_STREAM_END"); + rfbCloseSock(cl->sock); return(-1); + /*NOTREACHED*/ + case Z_STREAM_ERROR: + rfbLog("ZWriteExact: %s\n", "deflate returned Z_STREAM_ERROR"); + rfbCloseSock(cl->sock); return(-1); + /*NOTREACHED*/ + case Z_BUF_ERROR: + rfbLog("ZWriteExact: %s\n", "deflate returned Z_BUF_ERROR"); + rfbCloseSock(cl->sock); return(-1); + /*NOTREACHED*/ + default: + rfbLog("ZWriteExact: deflate returned %d", status); + rfbCloseSock(cl->sock); return(-1); + /*NOTREACHED*/ + } + } while (cl->Zstream->avail_out == 0); + return(1); + } + + int ListenOnTCPPort(port) int port; *** Xvnc/programs/Xserver/hw/vnc/stats.c 1999/11/06 02:35:25 1.1 --- Xvnc/programs/Xserver/hw/vnc/stats.c 1999/11/06 05:42:12 *************** *** 81,83 **** --- 81,94 ---- - cl->rfbBytesSent[rfbEncodingCopyRect])); } } + + void + rfbPrintZStats(rfbClientPtr cl) + { + if (cl->Zstream==NULL) return; /* Can't do anything */ + + rfbLog("zlib outgoing: raw %lu, compressed %lu, factor %.2f\n", + cl->Zstream->total_in, cl->Zstream->total_out, + cl->Zstream->total_in == 0 ? 0.0 : + (double) cl->Zstream->total_in / cl->Zstream->total_out); + } *** Xvnc/programs/Xserver/hw/vnc/translate.c 1999/11/06 01:12:31 1.1 --- Xvnc/programs/Xserver/hw/vnc/translate.c 1999/11/06 01:20:46 *************** *** 358,364 **** len += 256 * 3 * 2; ! if (WriteExact(cl->sock, buf, len) < 0) { rfbLogPerror("rfbSetClientColourMapBGR233: write"); rfbCloseSock(cl->sock); return FALSE; --- 358,364 ---- len += 256 * 3 * 2; ! if (ZWriteExact(cl, buf, len) < 0) { rfbLogPerror("rfbSetClientColourMapBGR233: write"); rfbCloseSock(cl->sock); return FALSE; *** include/rfbproto.h 1999/11/05 05:39:53 1.1 --- include/rfbproto.h 1999/11/05 05:53:42 *************** *** 208,213 **** --- 208,216 ---- * 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. + * + * In future versions of the protocol, the exchange of zlib details + * should be moved into here, with some spare fields for future use. */ typedef struct { *************** *** 238,244 **** /* * 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 --- 241,255 ---- /* * Following the server initialisation message it's up to the client to send ! * whichever protocol messages it wants. ! * ! * If a client want server-side zlib compression, then it should send ! * a rfbClientWantsZlibs message immediately. If the server supports ! * zlib compression, then it will send back a rfbServerZlibsOn reply. ! * Both sizes than then initialise the zlib functionality before futher ! * server messages are sent. ! * ! * After that, the client will typically 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 *************** *** 263,268 **** --- 274,280 ---- #define rfbSetColourMapEntries 1 #define rfbBell 2 #define rfbServerCutText 3 + #define rfbServerZlibsOn 10 /* client -> server */ *************** *** 274,279 **** --- 286,292 ---- #define rfbKeyEvent 4 #define rfbPointerEvent 5 #define rfbClientCutText 6 + #define rfbClientWantsZlibs 10 *************** *** 298,303 **** --- 311,327 ---- * *****************************************************************************/ + /*----------------------------------------------------------------------------- + * ServerZlibsOn - if the server sends this message, then all following + * messages will be compressed using zlib compression at the level chosen + * by the client. + */ + + typedef struct { + CARD8 type; /* always rfbServerZlibsOn */ + } rfbServerZlibsMsg; + + #define sz_rfbServerZlibsMsg 1 /*----------------------------------------------------------------------------- * FramebufferUpdate - a block of rectangles to be copied to the framebuffer. *************** *** 498,503 **** --- 522,528 ---- rfbSetColourMapEntriesMsg scme; rfbBellMsg b; rfbServerCutTextMsg sct; + rfbServerZlibsMsg zlibon; } rfbServerToClientMsg; *************** *** 510,515 **** --- 535,554 ---- /*----------------------------------------------------------------------------- + * ClientWantsZlibs - tell the RFB server that we want server-side zlib + * compression, and what level. Valid levels are 1 to 9. Levels outside + * of this may either be ignored by the server, or may be taken as a + * default value. A possible example: 0 -> ignore request, >9 -> level 9. + */ + + typedef struct { + CARD8 type; /* always rfbClientWantsZlibs */ + CARD8 level; /* level of zlib compression: 1 - 9 */ + } rfbClientWantsZlibsMsg; + + #define sz_rfbClientWantsZlibsMsg 2 + + /*----------------------------------------------------------------------------- * SetPixelFormat - tell the RFB server the format in which the client wants * pixels sent. */ *************** *** 668,671 **** --- 707,711 ---- rfbKeyEventMsg ke; rfbPointerEventMsg pe; rfbClientCutTextMsg cct; + rfbClientWantsZlibsMsg wantz; } rfbClientToServerMsg; *** vncviewer/Imakefile 1999/11/06 01:05:22 1.1 --- vncviewer/Imakefile 1999/11/06 01:05:53 *************** *** 14,22 **** INCLUDES = -I../include -I. VNCAUTH_LIB = ../libvncauth/libvncauth.a ! DEPLIBS = XawClientDepLibs $(VNCAUTH_LIB) ! LOCAL_LIBRARIES = XawClientLibs $(VNCAUTH_LIB) SRCS = \ argsresources.c \ --- 14,23 ---- INCLUDES = -I../include -I. VNCAUTH_LIB = ../libvncauth/libvncauth.a + ZLIB = ../Xvnc/lib/zlib/libz.a ! DEPLIBS = XawClientDepLibs $(VNCAUTH_LIB) $(ZLIB) ! LOCAL_LIBRARIES = XawClientLibs $(VNCAUTH_LIB) $(ZLIB) SRCS = \ argsresources.c \ *** vncviewer/argsresources.c 1999/11/05 05:57:46 1.1 --- vncviewer/argsresources.c 1999/11/05 05:59:29 *************** *** 168,173 **** --- 168,176 ---- {"requestedDepth", "RequestedDepth", XtRInt, sizeof(int), XtOffsetOf(AppData, requestedDepth), XtRImmediate, (XtPointer) 0}, + {"zlibCompression", "ZlibCompression", XtRInt, sizeof(int), + XtOffsetOf(AppData, zlibCompression), XtRImmediate, (XtPointer) 0}, + {"useSharedMemory", "UseSharedMemory", XtRBool, sizeof(Bool), XtOffsetOf(AppData, useShm), XtRImmediate, (XtPointer) True}, *************** *** 213,218 **** --- 216,222 ---- {"-truecolor", "*forceTrueColour", XrmoptionNoArg, "True"}, {"-truecolour", "*forceTrueColour", XrmoptionNoArg, "True"}, {"-depth", "*requestedDepth", XrmoptionSepArg, 0}, + {"-zlib", "*zlibCompression", XrmoptionSepArg, 0}, }; int numCmdLineOptions = XtNumber(cmdLineOptions); *** vncviewer/rfbproto.c 1999/11/05 06:07:44 1.1 --- vncviewer/rfbproto.c 1999/11/06 05:16:23 *************** *** 234,239 **** --- 234,255 ---- return True; } + /* + * Ask server for Zlib compression + */ + + Bool AskForZlib() + { + rfbClientWantsZlibsMsg wantz; + + wantz.type = rfbClientWantsZlibs; + wantz.level = appData.zlibCompression; + + if (!WriteExact(rfbsock, (char *)&wantz, sz_rfbClientWantsZlibsMsg)) + return False; + + return True; + } /* * SetFormatAndEncodings. *************** *** 414,419 **** --- 430,440 ---- return False; switch (msg.type) { + + case rfbServerZlibsOn: + printf("Server has turned zlib compression on\n"); + usingCompression=TRUE; + break; case rfbSetColourMapEntries: { *** vncviewer/sockets.c 1999/11/06 00:51:42 1.1 --- vncviewer/sockets.c 1999/11/07 00:25:56 *************** *** 31,46 **** --- 31,53 ---- #include #include #include + #include "../Xvnc/lib/zlib/zlib.h" void PrintInHex(char *buf, int len); + int Zread(int d, void *buf, size_t nbytes); Bool errorMessageOnReadFailure = True; #define BUF_SIZE 8192 static char buf[BUF_SIZE]; + static char Zbuf[BUF_SIZE]; static char *bufoutptr = buf; static int buffered = 0; + static z_streamp Zstream; /* Pointer to data structure used for */ + /* zlib decompression of server output */ + Bool usingCompression=FALSE; /* If TRUE, server data is compressed */ + /* * ReadFromRFBServer is called whenever we want to read some data from the RFB * server. It is non-trivial for two reasons: *************** *** 95,101 **** if (n <= BUF_SIZE) { while (buffered < n) { ! int i = read(rfbsock, buf + buffered, BUF_SIZE - buffered); if (i <= 0) { if (i < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) { --- 102,108 ---- if (n <= BUF_SIZE) { while (buffered < n) { ! int i = Zread(rfbsock, buf + buffered, BUF_SIZE - buffered); if (i <= 0) { if (i < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) { *************** *** 124,130 **** } else { while (n > 0) { ! int i = read(rfbsock, out, n); if (i <= 0) { if (i < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) { --- 131,137 ---- } else { while (n > 0) { ! int i = Zread(rfbsock, out, n); if (i <= 0) { if (i < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) { *************** *** 150,155 **** --- 157,231 ---- } } + int Zread(int d, void *buf, size_t nbytes) + { + int cnt,i,status; + + if (usingCompression==FALSE) return(read(d,buf,nbytes)); + + /* Try to read some stuff */ + if (Zstream->avail_in==0) { + i = read(rfbsock, Zbuf, sizeof(Zbuf)); + if (i<=0) return(i); + Zstream->next_in=Zbuf; + Zstream->avail_in=i; + } + + Zstream->next_out=buf; + Zstream->avail_out=nbytes; + + while(1) { + status = inflate(Zstream, Z_SYNC_FLUSH); + switch (status) { + case Z_OK: + cnt= nbytes - Zstream->avail_out; + if (cnt!=0) return(cnt); + + /* At this point, we have 0 bytes in the buffer. + * We can't return this, because it will be + * interpreted as EOF. Instead, if any avail_in left, + * we loop. Otherwise, we do another read(). + * Is there a better solution? Please tell. + */ + if (Zstream->avail_in!=0) continue; + + /* Try to read some more stuff */ + i = read(rfbsock, Zbuf, sizeof(Zbuf)); + if (i<=0) return(i); + Zstream->next_in=Zbuf; + Zstream->avail_in=i; + continue; + + case Z_STREAM_END: + fprintf(stderr, "Zread: inflate returned Z_STREAM_END\n"); + exit(1); + /*NOTREACHED*/ + case Z_DATA_ERROR: + fprintf(stderr, "Zread: inflate returned Z_DATA_ERROR\n"); + exit(1); + /*NOTREACHED*/ + case Z_STREAM_ERROR: + fprintf(stderr, "Zread: inflate returned Z_STREAM_ERROR\n"); + exit(1); + /*NOTREACHED*/ + case Z_BUF_ERROR: + /* Comments in zlib.h say that we should keep calling inflate() + until we get an error. This appears to be the error that we + get. */ + cnt= nbytes - Zstream->avail_out; + fprintf(stderr, "Zread: Z_BUF_ERROR %d\n",cnt); + return(cnt); + case Z_MEM_ERROR: + fprintf(stderr, "Zread: inflate returned Z_MEM_ERROR\n"); + exit(1); + /*NOTREACHED*/ + default: + fprintf(stderr, "Zread: inflate returned %d\n", status); + exit(1); + } + } + } + /* * Write an exact number of bytes, and don't return until you've sent them. *************** *** 417,420 **** --- 493,519 ---- } fflush(stderr); + } + + /* Initialise the z_stream data structure so that we can + * decompress the compressed server data stream. + * + * Returns TRUE if successful, FALSE otherwise + */ + + Bool InitZlib(void) + { + /* Create the z_stream data structure required */ + Zstream= (z_streamp)malloc(sizeof(z_stream)); + if (Zstream==NULL) return(FALSE); /* Failure, so no compression */ + + Zstream->zalloc= (alloc_func)Z_NULL; + Zstream->zfree= (free_func)Z_NULL; + Zstream->opaque= (void *)Z_NULL; + Zstream->next_in= (Bytef)Z_NULL; + Zstream->avail_in= 0; + + /* If failure in making stream, no compression */ + if (inflateInit(Zstream)!=Z_OK) return(FALSE); + return(TRUE); } *** vncviewer/vncviewer.c 1999/11/05 06:07:36 1.1 --- vncviewer/vncviewer.c 1999/11/06 03:06:02 *************** *** 109,114 **** --- 109,119 ---- DesktopInitAfterRealization(); + /* Ask the server for zlib compression, if we want it */ + if (appData.zlibCompression<0) appData.zlibCompression=0; + if (appData.zlibCompression>9) appData.zlibCompression=9; + if ((appData.zlibCompression!=0) && InitZlib()==TRUE) AskForZlib(); + /* Tell the VNC server which pixel format and encodings we want to use */ SetFormatAndEncodings(); *** vncviewer/vncviewer.h 1999/11/05 05:59:52 1.1 --- vncviewer/vncviewer.h 1999/11/06 03:06:34 *************** *** 68,73 **** --- 68,74 ---- Bool forceOwnCmap; Bool forceTrueColour; int requestedDepth; + int zlibCompression; Bool useShm; *************** *** 95,100 **** --- 96,102 ---- extern char vncServerHost[]; extern int vncServerPort; extern Bool listenSpecified; + extern Bool usingCompression; extern int listenPort, flashPort; extern XrmOptionDescRec cmdLineOptions[]; *************** *** 184,189 **** --- 186,192 ---- extern Bool ConnectToRFBServer(const char *hostname, int port); extern Bool InitialiseRFBConnection(); + extern Bool AskForZlib(); extern Bool SetFormatAndEncodings(); extern Bool SendIncrementalFramebufferUpdateRequest(); extern Bool SendFramebufferUpdateRequest(int x, int y, int w, int h, *************** *** 221,226 **** --- 224,231 ---- extern int StringToIPAddr(const char *str, unsigned int *addr); extern Bool SameMachine(int sock); + + extern Bool InitZlib(void); /* vncviewer.c */ *** Imakefile 1999/11/07 00:45:11 1.1 --- Imakefile 1999/11/07 00:45:21 *************** *** 1,7 **** #define IHaveSubdirs #define PassCDebugFlags ! SUBDIRS = libvncauth vncviewer vncpasswd World: make Makefiles --- 1,7 ---- #define IHaveSubdirs #define PassCDebugFlags ! SUBDIRS = libvncauth Xvnc/lib/zlib vncviewer vncpasswd World: make Makefiles