vnc.c

来自「winNT技术操作系统,国外开放的原代码和LIUX一样」· C语言 代码 · 共 1,377 行 · 第 1/3 页

C
1,377
字号
					text = &(text[i]);
					i = 0;
					for (j = 0; j < entry->size; j++)
						DO_GLYPH(((uint8 *) (entry->data)), j);
				}
				break;
			default:
				DO_GLYPH(text, i);
				i++;
				break;
		}
	}
}

void
ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
{
	vncBuffer *buf;

	buf = vncGetRect(server, x, y, cx, cy);
	offset *= TOBYTES(server->serverFormat.bitsPerPixel);
	cache_put_desktop(offset, cx, cy, cx, TOBYTES(server->serverFormat.bitsPerPixel),
			  (buf->data));
}

void
ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
{
	uint8 *data;
	vncBuffer *buf;
	int ox, oy, srcx, srcy;

	srcx = srcy = 0;
	ox = x;
	oy = y;

	offset *= TOBYTES(server->serverFormat.bitsPerPixel);
	data = cache_get_desktop(offset, cx, cy, TOBYTES(server->serverFormat.bitsPerPixel));
	if (data == NULL)
		return;

	buf = vncNewBuffer(cx, cy, 8);
	memcpy(buf->data, data, cx * cy * 1);

	if (vncwinClipRect(&x, &y, &cx, &cy))
	{
		srcx += x - ox;
		srcy += y - oy;
		vncCopyBlitFrom(server, x, y, cx, cy, buf, srcx, srcy);
	}
	vncDeleteBuffer(buf);
}

rfbPixelFormat vnc_formats[] = {
	/* bpp, depth,BE,TC, rmax, gmax, bmax, rsh, gsh, bsh  */
	{8, 8, 1, 0, 7, 7, 3, 0, 3, 6}
	,
	{16, 16, 1, 1, 31, 63, 31, 0, 5, 10}
	,
	{32, 24, 1, 1, 255, 255, 255, 0, 8, 16}
	,			//non-existant
	{32, 32, 1, 1, 2047, 2047, 1023, 0, 11, 22}
};

rfbPixelFormat *
vncNewFormat(int depth)
{
	return &(vnc_formats[(depth + 1) / 8 - 1]);
}

vncBuffer *
vncNewBuffer(int w, int h, int depth)
{
	vncBuffer *b = (vncBuffer *) xmalloc(sizeof(vncBuffer));
	b->format = vncNewFormat(depth);
	b->data = (void *) xmalloc(w * h * (b->format->bitsPerPixel / 8));
	b->owner = 1;
	b->w = w;
	b->h = h;
	b->linew = w;
	return b;
}

vncBuffer *
vncDupBuffer(vncBuffer * b)
{
	vncBuffer *buf = vncNewBuffer(b->w, b->h, b->format->depth);
	memcpy(buf->data, b->data, b->linew * b->h * b->format->bitsPerPixel / 8);
	return buf;
}

void
vncPrintStats()
{
	if (server && server->clientHead)
		rfbPrintStats(server->clientHead);
}

/* blit */

#define GETPIXEL(buf,x,y) \
     (((uint8_t*)(buf->data))[(x)+((y)*buf->linew)])
#define SETPIXEL(buf,x,y,p) \
     (((uint8_t*)(buf->data))[(x)+((y)*buf->linew)] = (uint8_t)p)

void
vncCopyBlitFromNoEncode(rfbScreenInfoPtr s, int x, int y, int w, int h,
			vncBuffer * src, int srcx, int srcy)
{
	int xx, yy;

	vncHideCursor();

	if (s->serverFormat.bitsPerPixel == src->format->bitsPerPixel
	    && srcx + w <= src->w && srcy + h <= src->h)
	{
		//simple copy
		uint8_t *srcdata, *dstdata;
		srcdata = src->data + (srcy * src->linew + srcx);
		dstdata = s->frameBuffer + (y * s->paddedWidthInBytes + x);
		for (yy = 0; yy < h; yy++)
		{
			memcpy(dstdata, srcdata, w);
			dstdata += s->paddedWidthInBytes;
			srcdata += src->linew;
		}
	}
	else
	{
		// xsrc,ysrc provide tiling copy support.
		for (yy = y; yy < y + h; yy++)
		{
			int ysrc = srcy + yy - y;
			while (ysrc >= src->h)
				ysrc -= src->h;
			for (xx = x; xx < x + w; xx++)
			{
				vncPixel p;
				int xsrc = srcx + xx - x;
				while (xsrc >= src->linew)
					xsrc -= src->linew;
				p = GETPIXEL(src, xsrc, ysrc);
				SETPIXEL(frameBuffer, xx, yy, p);
			}
		}
	}
}

void
vncCopyBlit(rfbScreenInfoPtr s, int x, int y, int w, int h, int srcx, int srcy)
{
	/* LibVNCServer already knows how to copy the data. */
	rfbDoCopyRect(s, x, y, x + w, y + h, x - srcx, y - srcy);
}

void
vncCopyBlitFrom(rfbScreenInfoPtr s, int x, int y, int w, int h, vncBuffer * src, int srcx, int srcy)
{
	vncCopyBlitFromNoEncode(s, x, y, w, h, src, srcx, srcy);
	rfbMarkRectAsModified(s, x, y, x + w, y + h);
}

void
vncTransBlitFrom(rfbScreenInfoPtr s, int x, int y, int w, int h,
		 vncBuffer * src, int srcx, int srcy, int bg)
{
	int xx, yy;

	vncHideCursor();

	// xsrc,ysrc provide tiling copy support.
	for (yy = y; yy < y + h; yy++)
	{
		int ysrc = srcy + yy - y;
		while (ysrc >= src->h)
			ysrc -= src->h;
		for (xx = x; xx < x + w; xx++)
		{
			vncPixel p;
			int xsrc = srcx + xx - x;
			while (xsrc >= src->linew)
				xsrc -= src->linew;
			p = GETPIXEL(src, xsrc, ysrc);
			// transparent blit!
			if (p != bg)
				SETPIXEL(frameBuffer, xx, yy, p);
		}
	}

	rfbMarkRectAsModified(s, x, y, x + w, y + h);
}

void
vncXorBlitFrom(rfbScreenInfoPtr s, int x, int y, int w, int h, vncBuffer * src, int srcx, int srcy)
{
	int xx, yy;

	vncHideCursor();

	// xsrc,ysrc provide tiling copy support.
	for (yy = y; yy < y + h; yy++)
	{
		int ysrc = srcy + yy - y;
		while (ysrc >= src->h)
			ysrc -= src->h;
		for (xx = x; xx < x + w; xx++)
		{
			vncPixel p, pp;
			int xsrc = srcx + xx - x;
			while (xsrc >= src->linew)
				xsrc -= src->linew;
			p = GETPIXEL(src, xsrc, ysrc);
			pp = GETPIXEL(frameBuffer, xx, yy);
			// xor blit!
			SETPIXEL(frameBuffer, xx, yy, p ^ pp);
		}
	}

	rfbMarkRectAsModified(s, x, y, x + w, y + h);
}

void
vncAndBlitFrom(rfbScreenInfoPtr s, int x, int y, int w, int h, vncBuffer * src, int srcx, int srcy)
{
	int xx, yy;

	vncHideCursor();

	// xsrc,ysrc provide tiling copy support.
	for (yy = y; yy < y + h; yy++)
	{
		int ysrc = srcy + yy - y;
		while (ysrc >= src->h)
			ysrc -= src->h;
		for (xx = x; xx < x + w; xx++)
		{
			vncPixel p, pp;
			int xsrc = srcx + xx - x;
			while (xsrc >= src->linew)
				xsrc -= src->linew;
			p = GETPIXEL(src, xsrc, ysrc);
			pp = GETPIXEL(frameBuffer, xx, yy);
			// and blit!
			SETPIXEL(frameBuffer, xx, yy, p & pp);
		}
	}

	rfbMarkRectAsModified(s, x, y, x + w, y + h);
}

void
vncDeleteBuffer(vncBuffer * b)
{
	if (b->owner)
		xfree(b->data);
	xfree(b);
}

/* cursor */
rfbCursorPtr
vncNewCursor(vncBuffer * mask, vncBuffer * pointer, int hotx, int hoty)
{
	int i, j, w = (mask->w + 7) / 8, mask_size = w * mask->h,
		pointer_size = pointer->w * pointer->h;
	rfbCursorPtr c = (rfbCursorPtr) xmalloc(sizeof(rfbCursor));

	if (mask->w != pointer->w || mask->h != pointer->h)
		error("ERROR! Mask is %dx%d, Pointer is %dx%d\n",
		      mask->w, mask->h, pointer->w, pointer->h);

	c->xhot = hotx;
	c->yhot = hoty;
	c->width = mask->w;
	c->height = mask->h;

	c->mask = (char *) xmalloc(mask_size);
	for (j = 0; j < c->height; j++)
		for (i = 0; i < w; i++)
			c->mask[j * w + i] =
				reverseByte[((unsigned char *) mask->data)[(j) * w + i]];
	vncDeleteBuffer(mask);

	c->source = 0;
	c->richSource = (char *) xmalloc(pointer_size);
	memcpy(c->richSource, pointer->data, pointer_size);
	vncDeleteBuffer(pointer);

	return c;
}

/* No FreeCursor, because the cursors are buffered. We only get a "HANDLE" */
void
vncSetCursor(rfbScreenInfoPtr s, rfbCursorPtr c)
{
	rfbSetCursor(s, c, FALSE);
}

/* these functions work even if vncBuffer's pixel format is not 1 byte/pixel */
vncPixel
vncGetPixel(vncBuffer * b, int x, int y)
{
	unsigned long offset = (x + (y * (b->linew))) * (b->format->bitsPerPixel >> 3);
	return ((uint8_t *) (b->data))[offset];
}

void
vncSetPixel(vncBuffer * b, int x, int y, vncPixel c)
{
	unsigned long offset = (x + (y * (b->linew))) * (b->format->bitsPerPixel >> 3);
	((uint8_t *) (b->data))[offset] = c;
}

void
vncSetRect(rfbScreenInfoPtr s, int x, int y, int w, int h, vncPixel c)
{
	int xx, yy;

	if (x + w > s->width)
		w = s->width - x;
	if (y + h > s->height)
		h = s->height - y;
	if (w <= 0 || h <= 0)
		return;

	vncHideCursor();

	// - Fill the rect in the local framebuffer
	if (s->serverFormat.bitsPerPixel == 8)
	{
		// - Simple 8-bit fill
		uint8_t *dstdata;
		dstdata = s->frameBuffer + (y * s->paddedWidthInBytes + x);
		for (yy = 0; yy < h; yy++)
		{
			memset(dstdata, c, w);
			dstdata += s->paddedWidthInBytes;
		}
	}
	else
	{
		for (yy = y; yy < y + h; yy++)
		{
			for (xx = x; xx < x + w; xx++)
			{
				SETPIXEL(frameBuffer, xx, yy, c);
			}
		}
	}

	rfbMarkRectAsModified(s, x, y, x + w, y + h);
}

vncBuffer *
vncGetRect(rfbScreenInfoPtr s, int x, int y, int w, int h)
{
	int xx, yy;
	vncBuffer *b = vncNewBuffer(w, h, s->serverFormat.depth);

	vncHideCursor();

	if (s->serverFormat.bitsPerPixel == 8)
	{
		//simple copy
		int srcstep, dststep;
		char *srcdata, *dstdata;
		srcstep = s->paddedWidthInBytes * s->serverFormat.bitsPerPixel / 8;
		dststep = w * s->serverFormat.bitsPerPixel / 8;
		dstdata = b->data;
		srcdata = s->frameBuffer + (y * srcstep + x * s->serverFormat.bitsPerPixel / 8);
		for (yy = 0; yy < h; yy++)
		{
			memcpy(dstdata, srcdata, dststep);
			dstdata += dststep;
			srcdata += srcstep;
		}
	}
	else
	{
		for (yy = y; yy < y + h; yy++)
		{
			for (xx = x; xx < x + w; xx++)
			{
				SETPIXEL(b, xx - x, yy - y, GETPIXEL(frameBuffer, xx, yy));
			}
		}
	}

	return b;
}

/* colourmap */

rfbColourMap *
vncNewColourMap(rfbScreenInfoPtr s, int n)
{
	rfbColourMap *m = (rfbColourMap *) xmalloc(sizeof(rfbColourMap));
	m->is16 = FALSE;
	m->count = n;
	m->data.bytes = (uint8_t *) xmalloc(n * 3);
	return m;
}

void
vncSetColourMapEntry(rfbColourMap * m, int i, vncPixel r, vncPixel g, vncPixel b)
{
	if (i < m->count)
	{
		m->data.bytes[3 * i + 0] = r;
		m->data.bytes[3 * i + 1] = g;
		m->data.bytes[3 * i + 2] = b;
	}
}

void
vncDeleteColourMap(rfbColourMap * m)
{
	if (m->data.bytes)
		free(m->data.bytes);
	m->count = 0;
}

void
vncSetColourMap(rfbScreenInfoPtr s, rfbColourMap * m)
{
	vncDeleteColourMap(&s->colourMap);
	s->colourMap = *m;
	rfbSetClientColourMaps(s, 0, 0);
}

void
ui_begin_update()
{
}

void
ui_end_update()
{
}

void
ui_resize_window()
{
	rfbClientIteratorPtr iter;
	rfbClientPtr cl;

	server->width = g_width;
	server->height = g_height;
	server->frameBuffer = (char *) realloc(server->frameBuffer, g_width * g_height);
	server->paddedWidthInBytes = g_width;

	iter = rfbGetClientIterator(server);
	while ((cl = rfbClientIteratorNext(iter)))
		if (cl->useNewFBSize)
			cl->newFBSizePending = TRUE;
		else
			rfbLog("Warning: Client %s does not support NewFBSize!\n ", cl->host);
	rfbReleaseClientIterator(iter);
}

⌨️ 快捷键说明

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