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

📄 translate.c

📁 远程桌面连接工具
💻 C
字号:
/* * translate.c - translate between different pixel formats *//* *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved. * *  This is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This software is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this software; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, *  USA. */#include <stdio.h>#include "rfb.h"static void PrintPixelFormat(rfbPixelFormat *pf);static Bool rfbSetClientColourMapBGR233();Bool rfbEconomicTranslate = FALSE;/* * Structure representing pixel format for RFB server (i.e. us). */rfbPixelFormat rfbServerFormat;/* * Some standard pixel formats. */static const rfbPixelFormat BGR233Format = {    8, 8, 0, 1, 7, 7, 3, 0, 3, 6};/* * Macro to compare pixel formats. */#define PF_EQ(x,y)							\	((x.bitsPerPixel == y.bitsPerPixel) &&				\	 (x.depth == y.depth) &&					\	 ((x.bigEndian == y.bigEndian) || (x.bitsPerPixel == 8)) &&	\	 (x.trueColour == y.trueColour) &&				\	 (!x.trueColour || ((x.redMax == y.redMax) &&			\			    (x.greenMax == y.greenMax) &&		\			    (x.blueMax == y.blueMax) &&			\			    (x.redShift == y.redShift) &&		\			    (x.greenShift == y.greenShift) &&		\			    (x.blueShift == y.blueShift))))#define CONCAT2(a,b) a##b#define CONCAT2E(a,b) CONCAT2(a,b)#define CONCAT4(a,b,c,d) a##b##c##d#define CONCAT4E(a,b,c,d) CONCAT4(a,b,c,d)#define OUT 8#include "tableinittctemplate.c"#include "tableinitcmtemplate.c"#define IN 8#include "tabletranstemplate.c"#undef IN#define IN 16#include "tabletranstemplate.c"#undef IN#define IN 32#include "tabletranstemplate.c"#undef IN#undef OUT#define OUT 16#include "tableinittctemplate.c"#include "tableinitcmtemplate.c"#define IN 8#include "tabletranstemplate.c"#undef IN#define IN 16#include "tabletranstemplate.c"#undef IN#define IN 32#include "tabletranstemplate.c"#undef IN#undef OUT#define OUT 32#include "tableinittctemplate.c"#include "tableinitcmtemplate.c"#define IN 8#include "tabletranstemplate.c"#undef IN#define IN 16#include "tabletranstemplate.c"#undef IN#define IN 32#include "tabletranstemplate.c"#undef IN#undef OUTtypedef void (*rfbInitTableFnType)(char **table, rfbPixelFormat *in,				   rfbPixelFormat *out);rfbInitTableFnType rfbInitTrueColourSingleTableFns[3] = {    rfbInitTrueColourSingleTable8,    rfbInitTrueColourSingleTable16,    rfbInitTrueColourSingleTable32};rfbInitTableFnType rfbInitColourMapSingleTableFns[3] = {    rfbInitColourMapSingleTable8,    rfbInitColourMapSingleTable16,    rfbInitColourMapSingleTable32};rfbInitTableFnType rfbInitTrueColourRGBTablesFns[3] = {    rfbInitTrueColourRGBTables8,    rfbInitTrueColourRGBTables16,    rfbInitTrueColourRGBTables32};rfbTranslateFnType rfbTranslateWithSingleTableFns[3][3] = {    { rfbTranslateWithSingleTable8to8,      rfbTranslateWithSingleTable8to16,      rfbTranslateWithSingleTable8to32 },    { rfbTranslateWithSingleTable16to8,      rfbTranslateWithSingleTable16to16,      rfbTranslateWithSingleTable16to32 },    { rfbTranslateWithSingleTable32to8,      rfbTranslateWithSingleTable32to16,      rfbTranslateWithSingleTable32to32 }};rfbTranslateFnType rfbTranslateWithRGBTablesFns[3][3] = {    { rfbTranslateWithRGBTables8to8,      rfbTranslateWithRGBTables8to16,      rfbTranslateWithRGBTables8to32 },    { rfbTranslateWithRGBTables16to8,      rfbTranslateWithRGBTables16to16,      rfbTranslateWithRGBTables16to32 },    { rfbTranslateWithRGBTables32to8,      rfbTranslateWithRGBTables32to16,      rfbTranslateWithRGBTables32to32 }};/* * rfbTranslateNone is used when no translation is required. */voidrfbTranslateNone(char *table, rfbPixelFormat *in, rfbPixelFormat *out,		 char *iptr, char *optr, int bytesBetweenInputLines,		 int width, int height){    int bytesPerOutputLine = width * (out->bitsPerPixel / 8);    while (height > 0) {	memcpy(optr, iptr, bytesPerOutputLine);	iptr += bytesBetweenInputLines;	optr += bytesPerOutputLine;	height--;    }}/* * rfbSetTranslateFunction sets the translation function. */BoolrfbSetTranslateFunction(cl)    rfbClientPtr cl;{    rfbLog("Pixel format for client %s:\n",cl->host);    PrintPixelFormat(&cl->format);    /*     * Check that bits per pixel values are valid     */    if ((rfbServerFormat.bitsPerPixel != 8) &&	(rfbServerFormat.bitsPerPixel != 16) &&	(rfbServerFormat.bitsPerPixel != 32))    {	rfbLog("%s: server bits per pixel not 8, 16 or 32\n",		"rfbSetTranslateFunction");	rfbCloseSock(cl->sock);	return FALSE;    }    if ((cl->format.bitsPerPixel != 8) &&	(cl->format.bitsPerPixel != 16) &&	(cl->format.bitsPerPixel != 32))    {	rfbLog("%s: client bits per pixel not 8, 16 or 32\n",		"rfbSetTranslateFunction");	rfbCloseSock(cl->sock);	return FALSE;    }    if (!rfbServerFormat.trueColour && (rfbServerFormat.bitsPerPixel != 8)) {	rfbLog("rfbSetTranslateFunction: server has colour map "		"but %d-bit - can only cope with 8-bit colour maps\n",		rfbServerFormat.bitsPerPixel);	rfbCloseSock(cl->sock);	return FALSE;    }    if (!cl->format.trueColour && (cl->format.bitsPerPixel != 8)) {	rfbLog("rfbSetTranslateFunction: client has colour map "		"but %d-bit - can only cope with 8-bit colour maps\n",		cl->format.bitsPerPixel);	rfbCloseSock(cl->sock);	return FALSE;    }    /*     * bpp is valid, now work out how to translate     */    if (!cl->format.trueColour) {	/* ? -> colour map */	if (!rfbServerFormat.trueColour) {	    /* colour map -> colour map */	    rfbLog("rfbSetTranslateFunction: both 8-bit colour map: "		    "no translation needed\n");	    cl->translateFn = rfbTranslateNone;	    return rfbSetClientColourMap(cl, 0, 0);	}	/*	 * truecolour -> colour map	 *	 * Set client's colour map to BGR233, then effectively it's	 * truecolour as well	 */	if (!rfbSetClientColourMapBGR233(cl))	    return FALSE;	cl->format = BGR233Format;    }    /* ? -> truecolour */    if (!rfbServerFormat.trueColour) {	/* colour map -> truecolour */	rfbLog("rfbSetTranslateFunction: client is %d-bit trueColour,"		" server has colour map\n",cl->format.bitsPerPixel);	cl->translateFn = rfbTranslateWithSingleTableFns			      [rfbServerFormat.bitsPerPixel / 16]				  [cl->format.bitsPerPixel / 16];	return rfbSetClientColourMap(cl, 0, 0);    }    /* truecolour -> truecolour */    if (PF_EQ(cl->format,rfbServerFormat)) {	/* client & server the same */	rfbLog("  no translation needed\n");	cl->translateFn = rfbTranslateNone;	return TRUE;    }    if ((rfbServerFormat.bitsPerPixel < 16) ||	(!rfbEconomicTranslate && (rfbServerFormat.bitsPerPixel == 16))) {	/* we can use a single lookup table for <= 16 bpp */	cl->translateFn = rfbTranslateWithSingleTableFns			      [rfbServerFormat.bitsPerPixel / 16]				  [cl->format.bitsPerPixel / 16];	(*rfbInitTrueColourSingleTableFns	    [cl->format.bitsPerPixel / 16]) (&cl->translateLookupTable,					     &rfbServerFormat, &cl->format);    } else {	/* otherwise we use three separate tables for red, green and blue */	cl->translateFn = rfbTranslateWithRGBTablesFns			      [rfbServerFormat.bitsPerPixel / 16]				  [cl->format.bitsPerPixel / 16];	(*rfbInitTrueColourRGBTablesFns	    [cl->format.bitsPerPixel / 16]) (&cl->translateLookupTable,					     &rfbServerFormat, &cl->format);    }    return TRUE;}/* * rfbSetClientColourMapBGR233 sets the client's colour map so that it's * just like an 8-bit BGR233 true colour client. */static BoolrfbSetClientColourMapBGR233(cl)    rfbClientPtr cl;{    char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2];    rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf;    CARD16 *rgb = (CARD16 *)(&buf[sz_rfbSetColourMapEntriesMsg]);    int i, len;    int r, g, b;    if (cl->format.bitsPerPixel != 8) {	rfbLog("%s: client not 8 bits per pixel\n",		"rfbSetClientColourMapBGR233");	rfbCloseSock(cl->sock);	return FALSE;    }    scme->type = rfbSetColourMapEntries;    scme->firstColour = Swap16IfLE(0);    scme->nColours = Swap16IfLE(256);    len = sz_rfbSetColourMapEntriesMsg;    i = 0;    for (b = 0; b < 4; b++) {	for (g = 0; g < 8; g++) {	    for (r = 0; r < 8; r++) {		rgb[i++] = Swap16IfLE(r * 65535 / 7);		rgb[i++] = Swap16IfLE(g * 65535 / 7);		rgb[i++] = Swap16IfLE(b * 65535 / 3);	    }	}    }    len += 256 * 3 * 2;    if (WriteExact(cl->sock, buf, len) < 0) {	rfbLogPerror("rfbSetClientColourMapBGR233: write");	rfbCloseSock(cl->sock);	return FALSE;    }    return TRUE;}/* * rfbSetClientColourMap is called to set the client's colour map.  If the * client is a true colour client, we simply update our own translation table * and mark the whole screen as having been modified. */BoolrfbSetClientColourMap(cl, firstColour, nColours)    rfbClientPtr cl;    int firstColour;    int nColours;{    EntryPtr pent;    int i, r, g, b;    BoxRec box;    if (nColours == 0) {	nColours = rfbInstalledColormap->pVisual->ColormapEntries;    }    if (rfbServerFormat.trueColour || !cl->readyForSetColourMapEntries) {	return TRUE;    }    if (cl->format.trueColour) {	(*rfbInitColourMapSingleTableFns	    [cl->format.bitsPerPixel / 16]) (&cl->translateLookupTable,					     &rfbServerFormat, &cl->format);	REGION_UNINIT(pScreen,&cl->modifiedRegion);	box.x1 = box.y1 = 0;	box.x2 = rfbScreen.width;	box.y2 = rfbScreen.height;	REGION_INIT(pScreen,&cl->modifiedRegion,&box,0);	return TRUE;    }    return rfbSendSetColourMapEntries(cl, firstColour, nColours);}/* * rfbSetClientColourMaps sets the colour map for each RFB client. */voidrfbSetClientColourMaps(firstColour, nColours)    int firstColour;    int nColours;{    rfbClientPtr cl, nextCl;    for (cl = rfbClientHead; cl; cl = nextCl) {	nextCl = cl->next;	rfbSetClientColourMap(cl, firstColour, nColours);    }}static voidPrintPixelFormat(pf)    rfbPixelFormat *pf;{    if (pf->bitsPerPixel == 1) {	rfbLog("  1 bpp, %s sig bit in each byte is leftmost on the screen.\n",	       (pf->bigEndian ? "most" : "least"));    } else {	rfbLog("  %d bpp, depth %d%s\n",pf->bitsPerPixel,pf->depth,	       ((pf->bitsPerPixel == 8) ? ""		: (pf->bigEndian ? ", big endian" : ", little endian")));	if (pf->trueColour) {	    rfbLog("  true colour: max r %d g %d b %d, shift r %d g %d b %d\n",		   pf->redMax, pf->greenMax, pf->blueMax,		   pf->redShift, pf->greenShift, pf->blueShift);	} else {	    rfbLog("  uses a colour map (not true colour).\n");	}    }}

⌨️ 快捷键说明

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