vnc.c
来自「winNT技术操作系统,国外开放的原代码和LIUX一样」· C语言 代码 · 共 1,377 行 · 第 1/3 页
C
1,377 行
}
}
cursor = (rfbCursorPtr) xmalloc(sizeof(rfbCursor));
cursor->width = width;
cursor->height = height;
cursor->xhot = x;
cursor->yhot = y;
cursor->mask = (char *) d0;
cursor->source = 0;
cursor->richSource = cdata;
cursor->cleanup = 0; // workaround: this produces a memleak
cursor->backRed = cursor->backGreen = cursor->backBlue = 0xffff;
cursor->foreRed = cursor->foreGreen = cursor->foreBlue = 0;
return (HCURSOR) cursor;
}
void
ui_set_cursor(HCURSOR cursor)
{
/* FALSE means: don't delete old cursor */
rfbSetCursor(server, (rfbCursorPtr) cursor, FALSE);
}
void
ui_destroy_cursor(HCURSOR cursor)
{
if (cursor)
rfbFreeCursor((rfbCursorPtr) cursor);
}
void
ui_set_null_cursor(void)
{
rfbSetCursor(server, 0, FALSE);
}
HGLYPH
ui_create_glyph(int width, int height, uint8 * data)
{
int x, y;
vncBuffer *buf;
buf = vncNewBuffer(width, height, 8);
//data is padded to multiple of 16bit line lengths
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
int byte = x / 8 + (y * ((width + 7) / 8));
byte = rfbEndianTest ? reverseByte[data[byte]] : data[byte];
byte = (byte >> (x & 7)) & 0x01;
vncSetPixel(buf, x, y, byte ? 0x7f : 0x00);
}
}
return (HGLYPH) buf;
}
void
ui_destroy_glyph(HGLYPH glyph)
{
ui_destroy_bitmap((HBITMAP) glyph);
}
HCOLOURMAP
ui_create_colourmap(COLOURMAP * colours)
{
int i;
rfbColourMap *map = vncNewColourMap(server, colours->ncolours);
for (i = 0; i < colours->ncolours; i++)
{
vncSetColourMapEntry(map, i, colours->colours[i].red,
colours->colours[i].green, colours->colours[i].blue);
}
return map;
}
void
ui_destroy_colourmap(HCOLOURMAP map)
{
vncDeleteColourMap(map);
}
void
ui_set_colourmap(HCOLOURMAP map)
{
vncSetColourMap(server, map);
}
void
ui_set_clip(int x, int y, int cx, int cy)
{
clipX = x;
clipY = y;
clipW = cx;
clipH = cy;
}
void
ui_reset_clip()
{
clipX = 0;
clipY = 0;
clipW = 64000;
clipH = 64000;
}
void
ui_bell()
{
rfbSendBell(server);
}
void
ui_destblt(uint8 opcode,
/* dest */ int x, int y, int cx, int cy)
{
int i;
vncBuffer *buf;
switch (opcode)
{
case 0:
case 15:
ui_rect(x, y, cx, cy, 0xff);
break;
case 5: // invert
buf = vncGetRect(server, x, y, cx, cy);
for (i = 0; i < cx * cy; i++)
((char *) (buf->data))[i] = !((char *) (buf->data))[i];
break;
default:
unimpl("ui_destblt: opcode=%d %d,%d %dx%d\n", opcode, x, y, cx, cy);
}
}
void
ui_patblt(uint8 opcode,
/* dest */ int x, int y, int cx, int cy,
/* brush */ BRUSH * brush, int bgcolour, int fgcolour)
{
switch (brush->style)
{
case 0: /* Solid */
switch (opcode)
{
case ROP2_XOR:
{
int xx, yy;
vncBuffer *fill = vncNewBuffer(cx, cy, 8);
for (yy = 0; yy < cy; yy++)
for (xx = 0; xx < cx; xx++)
vncSetPixel(fill, xx, yy, fgcolour);
if (vncwinClipRect(&x, &y, &cx, &cy))
vncXorBlitFrom(server, x, y, cx, cy, fill,
0, 0);
break;
}
default:
if (vncwinClipRect(&x, &y, &cx, &cy))
vncSetRect(server, x, y, cx, cy, fgcolour);
}
break;
case 3: /* Pattern */
{
int xx, yy;
vncBuffer *fill;
fill = (vncBuffer *) ui_create_glyph(8, 8, brush->pattern);
for (yy = 0; yy < 8; yy++)
{
for (xx = 0; xx < 8; xx++)
{
vncSetPixel(fill, xx, yy,
vncGetPixel(fill, xx,
yy) ? fgcolour : bgcolour);
}
}
if (vncwinClipRect(&x, &y, &cx, &cy))
{
switch (opcode)
{
case ROP2_COPY:
vncCopyBlitFrom(server, x, y, cx, cy, fill,
0, 0);
break;
case ROP2_XOR:
vncXorBlitFrom(server, x, y, cx, cy, fill,
0, 0);
break;
default:
unimpl("pattern blit (%d,%d) opcode=%d bg=%d fg=%d\n", x, y, opcode, bgcolour, fgcolour);
vncCopyBlitFrom(server, x, y, cx, cy, fill,
0, 0);
break;
}
}
ui_destroy_glyph((HGLYPH) fill);
break;
}
default:
unimpl("brush %d\n", brush->style);
}
}
void
ui_screenblt(uint8 opcode,
/* dest */ int x, int y, int cx, int cy,
/* src */ int srcx, int srcy)
{
int ox, oy;
ox = x;
oy = y;
if (vncwinClipRect(&x, &y, &cx, &cy))
{
//if we clipped top or left, we have to adjust srcx,srcy;
srcx += x - ox;
srcy += y - oy;
vncCopyBlit(server, x, y, cx, cy, srcx, srcy);
}
}
void
ui_memblt(uint8 opcode,
/* dest */ int x, int y, int cx, int cy,
/* src */ HBITMAP src, int srcx, int srcy)
{
int ox, oy;
ox = x;
oy = y;
if (vncwinClipRect(&x, &y, &cx, &cy))
{
//if we clipped top or left, we have to adjust srcx,srcy;
srcx += x - ox;
srcy += y - oy;
switch (ROP2_S(opcode))
{
case ROP2_OR:
vncTransBlitFrom(server, x, y, cx, cy, (vncBuffer *) src, srcx,
srcy, 0x0);
break;
case ROP2_XOR:
vncXorBlitFrom(server, x, y, cx, cy, (vncBuffer *) src, srcx, srcy);
break;
case ROP2_AND:
vncAndBlitFrom(server, x, y, cx, cy, (vncBuffer *) src, srcx, srcy);
break;
case ROP2_COPY:
vncCopyBlitFrom(server, x, y, cx, cy, (vncBuffer *) src, srcx,
srcy);
break;
default:
unimpl("ui_memblt: op%d %d,%d %dx%d\n", opcode, x, y, cx, cy);
vncCopyBlitFrom(server, x, y, cx, cy, (vncBuffer *) src, srcx,
srcy);
break;
}
}
}
void
ui_triblt(uint8 opcode,
/* dest */ int x, int y, int cx, int cy,
/* src */ HBITMAP src, int srcx, int srcy,
/* brush */ BRUSH * brush, int bgcolour, int fgcolour)
{
/* This is potentially difficult to do in general. Until someone
comes up with a more efficient way of doing it I am using cases. */
switch (opcode)
{
case 0x69: /* PDSxxn */
ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
break;
case 0xb8: /* PSDPxax */
ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
break;
default:
unimpl("ui_triblt 1x%x\n", opcode);
ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
}
}
void
ui_line(uint8 opcode,
/* dest */ int startx, int starty, int endx, int endy,
/* pen */ PEN * pen)
{
//vncSetRect(server,startx,starty,1+endx-startx,endy-starty,pen->colour);
//unimpl("drawline: pen colour=%d\n",pen->colour);
/* TODO: implement opcodes */
rfbDrawLine(server, startx, starty, endx, endy, pen->colour);
}
void
ui_rect(
/* dest */ int x, int y, int cx, int cy,
/* brush */ int colour)
{
if (vncwinClipRect(&x, &y, &cx, &cy))
{
vncSetRect(server, x, y, cx, cy, colour);
}
}
void
ui_draw_glyph(int mixmode,
/* dest */ int x, int y, int cx, int cy,
/* src */ HGLYPH glyph, int srcx, int srcy,
/* colours */ int bgcolour, int fgcolour)
{
int xx, yy;
int ox, oy;
vncBuffer *buf = vncDupBuffer(glyph);
x &= 0xffff;
y &= 0xffff;
/* yes, sometimes same fgcolour and bgcolour are sent, but because
* of transparency, we have to change that! */
if (mixmode == MIX_TRANSPARENT && fgcolour == bgcolour)
bgcolour = fgcolour ^ 0xff;
ox = x;
oy = y;
for (yy = srcy; yy < srcy + cy; yy++)
{
for (xx = srcx; xx < srcx + cx; xx++)
{
vncSetPixel(buf, xx, yy, vncGetPixel(buf, xx, yy) ? fgcolour : bgcolour);
}
}
switch (mixmode)
{
case MIX_TRANSPARENT:
if (vncwinClipRect(&x, &y, &cx, &cy))
{
//if we clipped top or left, we have to adjust srcx,srcy;
srcx += x - ox;
srcy += y - oy;
vncTransBlitFrom(server, x, y, cx, cy, buf, srcx, srcy, bgcolour);
}
break;
case MIX_OPAQUE:
if (vncwinClipRect(&x, &y, &cx, &cy))
{
//if we clipped top or left, we have to adjust srcx,srcy;
srcx += x - ox;
srcy += y - oy;
vncCopyBlitFrom(server, x, y, cx, cy, buf, srcx, srcy);
}
break;
default:
unimpl("mix %d\n", mixmode);
}
vncDeleteBuffer(buf);
}
#define DO_GLYPH(ttext,idx) \
{\
glyph = cache_get_font (font, ttext[idx]);\
if (!(flags & TEXT2_IMPLICIT_X))\
{\
offset = ttext[++idx];\
if ((offset & 0x80))\
offset = ((offset & 0x7f) << 8) | ttext[++idx];\
if (flags & TEXT2_VERTICAL)\
y += offset;\
else\
x += offset;\
}\
if (glyph != NULL)\
{\
ui_draw_glyph (mixmode, x + (short) glyph->offset,\
y + (short) glyph->baseline,\
glyph->width, glyph->height,\
glyph->pixmap, 0, 0, bgcolour, fgcolour);\
if (flags & TEXT2_IMPLICIT_X)\
x += glyph->width;\
}\
}
void
ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
int clipx, int clipy, int clipcx, int clipcy,
int boxx, int boxy, int boxcx, int boxcy,
int bgcolour, int fgcolour, uint8 * text, uint8 length)
{
FONTGLYPH *glyph;
int i, j, offset;
DATABLOB *entry;
if (boxcx > 1)
{
ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);
}
else if (mixmode == MIX_OPAQUE)
{
ui_rect(clipx, clipy, clipcx, clipcy, bgcolour);
}
/* Paint text, character by character */
for (i = 0; i < length;)
{
switch (text[i])
{
case 0xff:
if (i + 2 < length)
cache_put_text(text[i + 1], &(text[i - text[i + 2]]),
text[i + 2]);
else
{
error("this shouldn't be happening\n");
break;
}
/* this will move pointer from start to first character after FF command */
length -= i + 3;
text = &(text[i + 3]);
i = 0;
break;
case 0xfe:
entry = cache_get_text(text[i + 1]);
if (entry != NULL)
{
if ((((uint8 *) (entry->data))[1] == 0)
&& (!(flags & TEXT2_IMPLICIT_X)))
{
if (flags & 0x04) /* vertical text */
y += text[i + 2];
else
x += text[i + 2];
}
if (i + 2 < length)
i += 3;
else
i += 2;
length -= i;
/* this will move pointer from start to first character after FE command */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?