⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfbproto.c

📁 Microwindows genesis was with the NanoGUI project, and is now the primary distribution for both th
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory * *  This is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This software is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this software; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, *  USA. *//* * rfbproto.c - functions to deal with client side of RFB protocol. */#include <unistd.h>#include <errno.h>#include <pwd.h>#include <vncviewer.h>#ifndef NANOX#include <X11/Xatom.h>#endif#include <vncauth.h>static Bool HandleHextileEncoding8(int x, int y, int w, int h);static Bool HandleHextileEncoding16(int x, int y, int w, int h);static Bool HandleHextileEncoding32(int x, int y, int w, int h);int rfbsock;char *desktopName;rfbPixelFormat myFormat;rfbServerInitMsg si;struct timeval updateRequestTime;Bool sendUpdateRequest;int endianTest = 1;/* note that the CoRRE encoding uses this buffer and assumes it is big enough   to hold 255 * 255 * 32 bits -> 260100 bytes.  640*480 = 307200 bytes *//* also hextile assumes it is big enough to hold 16 * 16 * 32 bits */#define BUFFER_SIZE (640*480)static char buffer[BUFFER_SIZE];void PrintPixelFormat(rfbPixelFormat *format);/* * ConnectToRFBServer. */BoolConnectToRFBServer(const char *hostname, int port){    unsigned int host;    if (!StringToIPAddr(hostname, &host)) {	fprintf(stderr,"%s: couldn't convert '%s' to host address\n",		programName,hostname);	return False;    }    rfbsock = ConnectToTcpAddr(host, port);    if (rfbsock < 0) {	fprintf(stderr,"%s: unable to connect to VNC server\n",		programName);	return False;    }    return True;}/* * InitialiseRFBConnection. */BoolInitialiseRFBConnection(int sock){    rfbProtocolVersionMsg pv;    int major,minor;    Bool authWillWork = True;    CARD32 authScheme, reasonLen, authResult;    char *reason;    CARD8 challenge[CHALLENGESIZE];    char *passwd;    int i;    rfbClientInitMsg ci;    /* if the connection is immediately closed, don't report anything, so       that pmw's monitor can make test connections */    if (listenSpecified)	errorMessageFromReadExact = False;    if (!ReadExact(sock, pv, sz_rfbProtocolVersionMsg)) return False;    errorMessageFromReadExact = True;    pv[sz_rfbProtocolVersionMsg] = 0;    if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {	fprintf(stderr,"%s: Not a valid VNC server\n",programName);	return False;    }    fprintf(stderr,"%s: VNC server supports protocol version %d.%d "	    "(viewer %d.%d)\n",	    programName,major,minor,rfbProtocolMajorVersion,	    rfbProtocolMinorVersion);    if ((major == 3) && (minor < 3)) {	/* if server is before 3.3 authentication won't work */	authWillWork = False;    } else {	/* any other server version, just tell it what we want */	major = rfbProtocolMajorVersion;	minor = rfbProtocolMinorVersion;    }    sprintf(pv,rfbProtocolVersionFormat,major,minor);    if (!WriteExact(sock, pv, sz_rfbProtocolVersionMsg)) return False;    if (!ReadExact(sock, (char *)&authScheme, 4)) return False;    authScheme = Swap32IfLE(authScheme);    switch (authScheme) {    case rfbConnFailed:	if (!ReadExact(sock, (char *)&reasonLen, 4)) return False;	reasonLen = Swap32IfLE(reasonLen);	reason = malloc(reasonLen);	if (!ReadExact(sock, reason, reasonLen)) return False;	fprintf(stderr,"%s: VNC connection failed: %.*s\n",		programName, (int)reasonLen, reason);	return False;    case rfbNoAuth:	fprintf(stderr,"%s: No authentication needed\n",programName);	break;    case rfbVncAuth:	if (!authWillWork) {	    fprintf(stderr,		    "\n%s: VNC server uses the old authentication scheme.\n"		    "You should kill your old desktop(s) and restart.\n"		    "If you really need to connect to this desktop use "		    "vncviewer3.2\n\n",		    programName);	    return False;	}	if (!ReadExact(sock, (char *)challenge, CHALLENGESIZE)) return False;	if (passwdFile) {	    passwd = vncDecryptPasswdFromFile(passwdFile);	} else {	    static char pass[32] = {"foobar2"};	    passwd = pass;	    /* passwd = getpass("Password: "); */	    if (strlen(passwd) == 0) {		fprintf(stderr,"%s: Reading password failed\n",programName);		return False;	    }	    if (strlen(passwd) > 8) {		passwd[8] = '\0';	    }	}	vncEncryptBytes(challenge, passwd);	/* Lose the password from memory */	for (i=0; i<strlen(passwd); i++) {	    passwd[i] = '\0';	}	if (!WriteExact(sock, (char *)challenge, CHALLENGESIZE)) return False;	if (!ReadExact(sock, (char *)&authResult, 4)) return False;	authResult = Swap32IfLE(authResult);	switch (authResult) {	case rfbVncAuthOK:	    fprintf(stderr,"%s: VNC authentication succeeded\n",programName);	    break;	case rfbVncAuthFailed:	    fprintf(stderr,"%s: VNC authentication failed\n",programName);	    return False;	case rfbVncAuthTooMany:	    fprintf(stderr,"%s: VNC authentication failed - too many tries\n",		    programName);	    return False;	default:	    fprintf(stderr,"%s: Unknown VNC authentication result: %d\n",		    programName,(int)authResult);	    return False;	}	break;    default:	fprintf(stderr,		"%s: Unknown authentication scheme from VNC server: %d\n",		programName,(int)authScheme);	return False;    }    ci.shared = (shareDesktop ? 1 : 0);    if (!WriteExact(sock, (char *)&ci, sz_rfbClientInitMsg)) return False;    if (!ReadExact(sock, (char *)&si, sz_rfbServerInitMsg)) return False;    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 (((updateRequestX + updateRequestW) > si.framebufferWidth) ||	((updateRequestY + updateRequestH) > si.framebufferHeight))    {	fprintf(stderr,		"%s: region requested is outside server's framebuffer\n",		programName);	return False;    }    if (updateRequestW == 0)	updateRequestW = si.framebufferWidth - updateRequestX;    if (updateRequestH == 0)	updateRequestH = si.framebufferHeight - updateRequestY;    desktopName = malloc(si.nameLength + 1);    if (!ReadExact(sock, desktopName, si.nameLength)) return False;    desktopName[si.nameLength] = 0;    fprintf(stderr,"%s: Desktop name \"%s\"\n",programName,desktopName);    fprintf(stderr,	    "%s: Connected to VNC server, using protocol version %d.%d\n",	    programName, rfbProtocolMajorVersion, rfbProtocolMinorVersion);    fprintf(stderr,"%s: VNC server default format:\n",programName);    PrintPixelFormat(&si.format);    return True;}/* * SetFormatAndEncodings. */BoolSetFormatAndEncodings(){    rfbSetPixelFormatMsg spf;    char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];    rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;    CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]);    int len = 0;    int i;    spf.type = rfbSetPixelFormat;    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->nEncodings = 0;    for (i = 0; i < nExplicitEncodings; i++) {	encs[se->nEncodings++] = Swap32IfLE(explicitEncodings[i]);    }    if (SameMachine(rfbsock)) {	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);    }    if (addCopyRect)	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);    if (addHextile)	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);    if (addCoRRE)	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);    if (addRRE)	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE);    len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;    se->nEncodings = Swap16IfLE(se->nEncodings);    if (!WriteExact(rfbsock, buf, len)) return False;    return True;}/* * SendIncrementalFramebufferUpdateRequest. */BoolSendIncrementalFramebufferUpdateRequest(){    return SendFramebufferUpdateRequest(updateRequestX, updateRequestY,					updateRequestW, updateRequestH, True);}/* * SendFramebufferUpdateRequest. */BoolSendFramebufferUpdateRequest(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;    gettimeofday(&updateRequestTime, NULL);    sendUpdateRequest = False;    return True;}/* * SendPointerEvent. */BoolSendPointerEvent(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. */BoolSendKeyEvent(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. */BoolSendClientCutText(char *str, int len){    rfbClientCutTextMsg cct;    cct.type = rfbClientCutText;    cct.length = Swap32IfLE(len);    return  (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) &&	     WriteExact(rfbsock, str, len));}/* * HandleRFBServerMessage. */BoolHandleRFBServerMessage(){    rfbServerToClientMsg msg;    if (!ReadExact(rfbsock, (char *)&msg, 1))	return False;    switch (msg.type) {    case rfbSetColourMapEntries:    {	int i;	CARD16 rgb[3];	XColor xc;	if (!ReadExact(rfbsock, ((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 (!ReadExact(rfbsock, (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;/* printf("XStoreColor (%d,%d,%d) = %d\n", xc.red>>8, xc.green>>8, xc.blue>>8, xc.pixel); */	    XStoreColor(dpy, cmap, &xc);	}	break;    }    case rfbFramebufferUpdate:    {	rfbFramebufferUpdateRectHeader rect;	int linesToRead;	int bytesPerLine;	int i;	if (!ReadExact(rfbsock, ((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 (!ReadExact(rfbsock, (char *)&rect,			     sz_rfbFramebufferUpdateRectHeader))		return False;	    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);	    rect.encoding = Swap32IfLE(rect.encoding);	    if ((rect.r.x + rect.r.w > si.framebufferWidth) ||		(rect.r.y + rect.r.h > si.framebufferHeight))	    {		fprintf(stderr,"%s: rect too large: %dx%d at (%d, %d)\n",		       programName, rect.r.w, rect.r.h, rect.r.x, rect.r.y);		return False;	    }	    if ((rect.r.h * rect.r.w) == 0) {		fprintf(stderr,"%s: zero size rect - ignoring\n",programName);		continue;	    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -