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 + -
显示快捷键?