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

📄 rfbserver.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 3 页
字号:
	for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) {	    int x = REGION_RECTS(&updateRegion)[i].x1;	    int y = REGION_RECTS(&updateRegion)[i].y1;	    int w = REGION_RECTS(&updateRegion)[i].x2 - x;	    int h = REGION_RECTS(&updateRegion)[i].y2 - y;	    nUpdateRegionRects += (((h-1) / (ZLIB_MAX_SIZE( w ) / w)) + 1);	}    } else if (cl->preferredEncoding == rfbEncodingTight) {	nUpdateRegionRects = 0;	for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) {	    int x = REGION_RECTS(&updateRegion)[i].x1;	    int y = REGION_RECTS(&updateRegion)[i].y1;	    int w = REGION_RECTS(&updateRegion)[i].x2 - x;	    int h = REGION_RECTS(&updateRegion)[i].y2 - y;	    int n = rfbNumCodedRectsTight(cl, x, y, w, h);	    if (n == 0) {		nUpdateRegionRects = 0xFFFF;		break;	    }	    nUpdateRegionRects += n;	}    } else {	nUpdateRegionRects = REGION_NUM_RECTS(&updateRegion);    }    fu->type = rfbFramebufferUpdate;    if (nUpdateRegionRects != 0xFFFF) {	fu->nRects = Swap16IfLE(REGION_NUM_RECTS(&updateCopyRegion) +				nUpdateRegionRects +				!!sendCursorShape + !!sendCursorPos);    } else {	fu->nRects = 0xFFFF;    }    ublen = sz_rfbFramebufferUpdateMsg;    if (sendCursorShape) {	cl->cursorWasChanged = FALSE;	if (!rfbSendCursorShape(cl, pScreen))	    return FALSE;    }    if (sendCursorPos) {	cl->cursorWasMoved = FALSE;	if (!rfbSendCursorPos(cl, pScreen)) 	    return FALSE;    }    if (REGION_NOTEMPTY(pScreen,&updateCopyRegion)) {	if (!rfbSendCopyRegion(cl,&updateCopyRegion,dx,dy)) {	    REGION_UNINIT(pScreen,&updateRegion);	    REGION_UNINIT(pScreen,&updateCopyRegion);	    return FALSE;	}    }    REGION_UNINIT(pScreen,&updateCopyRegion);    for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) {	int x = REGION_RECTS(&updateRegion)[i].x1;	int y = REGION_RECTS(&updateRegion)[i].y1;	int w = REGION_RECTS(&updateRegion)[i].x2 - x;	int h = REGION_RECTS(&updateRegion)[i].y2 - y;	cl->rfbRawBytesEquivalent += (sz_rfbFramebufferUpdateRectHeader				      + w * (cl->format.bitsPerPixel / 8) * h);	switch (cl->preferredEncoding) {	case rfbEncodingRaw:	    if (!rfbSendRectEncodingRaw(cl, x, y, w, h)) {		REGION_UNINIT(pScreen,&updateRegion);		return FALSE;	    }	    break;	case rfbEncodingRRE:	    if (!rfbSendRectEncodingRRE(cl, x, y, w, h)) {		REGION_UNINIT(pScreen,&updateRegion);		return FALSE;	    }	    break;	case rfbEncodingCoRRE:	    if (!rfbSendRectEncodingCoRRE(cl, x, y, w, h)) {		REGION_UNINIT(pScreen,&updateRegion);		return FALSE;	    }	    break;	case rfbEncodingHextile:	    if (!rfbSendRectEncodingHextile(cl, x, y, w, h)) {		REGION_UNINIT(pScreen,&updateRegion);		return FALSE;	    }	    break;	case rfbEncodingZlib:	    if (!rfbSendRectEncodingZlib(cl, x, y, w, h)) {		REGION_UNINIT(pScreen,&updateRegion);		return FALSE;	    }	    break;	case rfbEncodingTight:	    if (!rfbSendRectEncodingTight(cl, x, y, w, h)) {		REGION_UNINIT(pScreen,&updateRegion);		return FALSE;	    }	    break;	}    }    REGION_UNINIT(pScreen,&updateRegion);    if (nUpdateRegionRects == 0xFFFF && !rfbSendLastRectMarker(cl))	return FALSE;    if (!rfbSendUpdateBuf(cl))	return FALSE;    return TRUE;}/* * Send the copy region as a string of CopyRect encoded rectangles. * The only slightly tricky thing is that we should send the messages in * the correct order so that an earlier CopyRect will not corrupt the source * of a later one. */static BoolrfbSendCopyRegion(cl, reg, dx, dy)    rfbClientPtr cl;    RegionPtr reg;    int dx, dy;{    int nrects, nrectsInBand, x_inc, y_inc, thisRect, firstInNextBand;    int x, y, w, h;    rfbFramebufferUpdateRectHeader rect;    rfbCopyRect cr;    nrects = REGION_NUM_RECTS(reg);    if (dx <= 0) {	x_inc = 1;    } else {	x_inc = -1;    }    if (dy <= 0) {	thisRect = 0;	y_inc = 1;    } else {	thisRect = nrects - 1;	y_inc = -1;    }    while (nrects > 0) {	firstInNextBand = thisRect;	nrectsInBand = 0;	while ((nrects > 0) &&	       (REGION_RECTS(reg)[firstInNextBand].y1		== REGION_RECTS(reg)[thisRect].y1))	{	    firstInNextBand += y_inc;	    nrects--;	    nrectsInBand++;	}	if (x_inc != y_inc) {	    thisRect = firstInNextBand - y_inc;	}	while (nrectsInBand > 0) {	    if ((ublen + sz_rfbFramebufferUpdateRectHeader		 + sz_rfbCopyRect) > UPDATE_BUF_SIZE)	    {		if (!rfbSendUpdateBuf(cl))		    return FALSE;	    }	    x = REGION_RECTS(reg)[thisRect].x1;	    y = REGION_RECTS(reg)[thisRect].y1;	    w = REGION_RECTS(reg)[thisRect].x2 - x;	    h = REGION_RECTS(reg)[thisRect].y2 - y;	    rect.r.x = Swap16IfLE(x);	    rect.r.y = Swap16IfLE(y);	    rect.r.w = Swap16IfLE(w);	    rect.r.h = Swap16IfLE(h);	    rect.encoding = Swap32IfLE(rfbEncodingCopyRect);	    memcpy(&updateBuf[ublen], (char *)&rect,		   sz_rfbFramebufferUpdateRectHeader);	    ublen += sz_rfbFramebufferUpdateRectHeader;	    cr.srcX = Swap16IfLE(x - dx);	    cr.srcY = Swap16IfLE(y - dy);	    memcpy(&updateBuf[ublen], (char *)&cr, sz_rfbCopyRect);	    ublen += sz_rfbCopyRect;	    cl->rfbRectanglesSent[rfbEncodingCopyRect]++;	    cl->rfbBytesSent[rfbEncodingCopyRect]		+= sz_rfbFramebufferUpdateRectHeader + sz_rfbCopyRect;	    thisRect += x_inc;	    nrectsInBand--;	}	thisRect = firstInNextBand;    }    return TRUE;}/* * Send a given rectangle in raw encoding (rfbEncodingRaw). */BoolrfbSendRectEncodingRaw(cl, x, y, w, h)    rfbClientPtr cl;    int x, y, w, h;{    rfbFramebufferUpdateRectHeader rect;    int nlines;    int bytesPerLine = w * (cl->format.bitsPerPixel / 8);    char *fbptr = (rfbScreen.pfbMemory + (rfbScreen.paddedWidthInBytes * y)		   + (x * (rfbScreen.bitsPerPixel / 8)));    /* Flush the buffer to guarantee correct alignment for translateFn(). */    if (ublen > 0) {	if (!rfbSendUpdateBuf(cl))	    return FALSE;    }    rect.r.x = Swap16IfLE(x);    rect.r.y = Swap16IfLE(y);    rect.r.w = Swap16IfLE(w);    rect.r.h = Swap16IfLE(h);    rect.encoding = Swap32IfLE(rfbEncodingRaw);    memcpy(&updateBuf[ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader);    ublen += sz_rfbFramebufferUpdateRectHeader;    cl->rfbRectanglesSent[rfbEncodingRaw]++;    cl->rfbBytesSent[rfbEncodingRaw]	+= sz_rfbFramebufferUpdateRectHeader + bytesPerLine * h;    nlines = (UPDATE_BUF_SIZE - ublen) / bytesPerLine;    while (TRUE) {	if (nlines > h)	    nlines = h;	(*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat,			   &cl->format, fbptr, &updateBuf[ublen],			   rfbScreen.paddedWidthInBytes, w, nlines);	ublen += nlines * bytesPerLine;	h -= nlines;	if (h == 0)	/* rect fitted in buffer, do next one */	    return TRUE;	/* buffer full - flush partial rect and do another nlines */	if (!rfbSendUpdateBuf(cl))	    return FALSE;	fbptr += (rfbScreen.paddedWidthInBytes * nlines);	nlines = (UPDATE_BUF_SIZE - ublen) / bytesPerLine;	if (nlines == 0) {	    rfbLog("rfbSendRectEncodingRaw: send buffer too small for %d "		   "bytes per line\n", bytesPerLine);	    rfbCloseSock(cl->sock);	    return FALSE;	}    }}/* * Send an empty rectangle with encoding field set to value of * rfbEncodingLastRect to notify client that this is the last * rectangle in framebuffer update ("LastRect" extension of RFB * protocol). */static BoolrfbSendLastRectMarker(cl)    rfbClientPtr cl;{    rfbFramebufferUpdateRectHeader rect;    if (ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {	if (!rfbSendUpdateBuf(cl))	    return FALSE;    }    rect.encoding = Swap32IfLE(rfbEncodingLastRect);    rect.r.x = 0;    rect.r.y = 0;    rect.r.w = 0;    rect.r.h = 0;    memcpy(&updateBuf[ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader);    ublen += sz_rfbFramebufferUpdateRectHeader;    cl->rfbLastRectMarkersSent++;    cl->rfbLastRectBytesSent += sz_rfbFramebufferUpdateRectHeader;    return TRUE;}/* * Send the contents of updateBuf.  Returns 1 if successful, -1 if * not (errno should be set). */BoolrfbSendUpdateBuf(cl)    rfbClientPtr cl;{    /*    int i;    for (i = 0; i < ublen; i++) {	fprintf(stderr,"%02x ",((unsigned char *)updateBuf)[i]);    }    fprintf(stderr,"\n");    */    if (ublen > 0 && WriteExact(cl->sock, updateBuf, ublen) < 0) {	rfbLogPerror("rfbSendUpdateBuf: write");	rfbCloseSock(cl->sock);	return FALSE;    }    ublen = 0;    return TRUE;}/* * rfbSendSetColourMapEntries sends a SetColourMapEntries message to the * client, using values from the currently installed colormap. */BoolrfbSendSetColourMapEntries(cl, firstColour, nColours)    rfbClientPtr cl;    int firstColour;    int nColours;{    char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2];    rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf;    CARD16 *rgb = (CARD16 *)(&buf[sz_rfbSetColourMapEntriesMsg]);    EntryPtr pent;    int i, len;    scme->type = rfbSetColourMapEntries;    scme->firstColour = Swap16IfLE(firstColour);    scme->nColours = Swap16IfLE(nColours);    len = sz_rfbSetColourMapEntriesMsg;    pent = (EntryPtr)&rfbInstalledColormap->red[firstColour];    for (i = 0; i < nColours; i++) {	if (pent->fShared) {	    rgb[i*3] = Swap16IfLE(pent->co.shco.red->color);	    rgb[i*3+1] = Swap16IfLE(pent->co.shco.green->color);	    rgb[i*3+2] = Swap16IfLE(pent->co.shco.blue->color);	} else {	    rgb[i*3] = Swap16IfLE(pent->co.local.red);	    rgb[i*3+1] = Swap16IfLE(pent->co.local.green);	    rgb[i*3+2] = Swap16IfLE(pent->co.local.blue);	}	pent++;    }    len += nColours * 3 * 2;    if (WriteExact(cl->sock, buf, len) < 0) {	rfbLogPerror("rfbSendSetColourMapEntries: write");	rfbCloseSock(cl->sock);	return FALSE;    }    return TRUE;}/* * rfbSendBell sends a Bell message to all the clients. */voidrfbSendBell(){    rfbClientPtr cl, nextCl;    rfbBellMsg b;    for (cl = rfbClientHead; cl; cl = nextCl) {	nextCl = cl->next;	if (cl->state != RFB_NORMAL)	  continue;	b.type = rfbBell;	if (WriteExact(cl->sock, (char *)&b, sz_rfbBellMsg) < 0) {	    rfbLogPerror("rfbSendBell: write");	    rfbCloseSock(cl->sock);	}    }}/* * rfbSendServerCutText sends a ServerCutText message to all the clients. */voidrfbSendServerCutText(char *str, int len){    rfbClientPtr cl, nextCl;    rfbServerCutTextMsg sct;    if (rfbViewOnly)	return;    for (cl = rfbClientHead; cl; cl = nextCl) {	nextCl = cl->next;	if (cl->state != RFB_NORMAL || cl->viewOnly)	  continue;	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);	}    }}/***************************************************************************** * * UDP can be used for keyboard and pointer events when the underlying * network is highly reliable.  This is really here to support ORL's * videotile, whose TCP implementation doesn't like sending lots of small * packets (such as 100s of pen readings per second!). */voidrfbNewUDPConnection(sock)    int sock;{    if (write(sock, &ptrAcceleration, 1) < 0) {	rfbLogPerror("rfbNewUDPConnection: write");    }}/* * Because UDP is a message based service, we can't read the first byte and * then the rest of the packet separately like we do with TCP.  We will always * get a whole packet delivered in one go, so we ask read() for the maximum * number of bytes we can possibly get. */voidrfbProcessUDPInput(sock)    int sock;{    int n;    rfbClientToServerMsg msg;    if ((n = read(sock, (char *)&msg, sizeof(msg))) <= 0) {	if (n < 0) {	    rfbLogPerror("rfbProcessUDPInput: read");	}	rfbDisconnectUDPSock();	return;    }    switch (msg.type) {    case rfbKeyEvent:	if (n != sz_rfbKeyEventMsg) {	    rfbLog("rfbProcessUDPInput: key event incorrect length\n");	    rfbDisconnectUDPSock();	    return;	}	if (!rfbViewOnly) {	    KbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), 0);	}	break;    case rfbPointerEvent:	if (n != sz_rfbPointerEventMsg) {	    rfbLog("rfbProcessUDPInput: ptr event incorrect length\n");	    rfbDisconnectUDPSock();	    return;	}	if (!rfbViewOnly) {	    PtrAddEvent(msg.pe.buttonMask,			Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), 0);	}	break;    default:	rfbLog("rfbProcessUDPInput: unknown message type %d\n",	       msg.type);	rfbDisconnectUDPSock();    }}

⌨️ 快捷键说明

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