cleaned up warnings, cursor changes

pull/1/head
dscho 23 years ago
parent febced5536
commit 1e83d9a599

@ -20,10 +20,10 @@ OSX_LIBS = -framework ApplicationServices -framework Carbon
SOURCES=main.c rfbserver.c miregion.c auth.c sockets.c xalloc.c \ SOURCES=main.c rfbserver.c miregion.c auth.c sockets.c xalloc.c \
stats.c corre.c hextile.c rre.c translate.c cutpaste.c \ stats.c corre.c hextile.c rre.c translate.c cutpaste.c \
zlib.c tight.c httpd.c zlib.c tight.c httpd.c cursor.o
OBJS=main.o rfbserver.o miregion.o auth.o sockets.o xalloc.o \ OBJS=main.o rfbserver.o miregion.o auth.o sockets.o xalloc.o \
stats.o corre.o hextile.o rre.o translate.o cutpaste.o \ stats.o corre.o hextile.o rre.o translate.o cutpaste.o \
zlib.o tight.o httpd.o zlib.o tight.o httpd.o cursor.o
all: example pnmshow storepasswd all: example pnmshow storepasswd

@ -1,6 +1,15 @@
LibVNCServer: a library for easy implementation of a RDP/VNC server. LibVNCServer: a library for easy implementation of a RDP/VNC server.
Copyright (C) 2001 Johannes E. Schindelin Copyright (C) 2001 Johannes E. Schindelin
What is it?
-----------
VNC is set of programs using the RFB (Remote Frame Buffer) protocol. They
are designed to "export" a frame buffer via net. It is already in wide use
for administration, but it is not that easy to make a server yourself.
This has been changed by LibVNCServer.
There are two examples included: There are two examples included:
- example, a shared scribble sheet - example, a shared scribble sheet
- pnmshow, a program to show PNMs (pictures) over the net. - pnmshow, a program to show PNMs (pictures) over the net.
@ -12,13 +21,56 @@ How to use
---------- ----------
To make a server, you just have to initialise a server structure using the To make a server, you just have to initialise a server structure using the
function rfbDefaultScreenInit. function rfbDefaultScreenInit, like
rfbScreenInfoPtr rfbScreen =
rfbDefaultScreenInit(argc,argv,maxx,maxy,8,3,bpp);
You then can set hooks and io functions. You then can set hooks and io functions (see below).
You can use a blocking event loop, a background (pthread based) event loop, You can use a blocking event loop, a background (pthread based) event loop,
or implement your own using the processEvents function. or implement your own using the processEvents function.
Also, there is functionality included to draw a cursor (see below).
To start also an HTTP server (running on port 5800+display_number), you have
to set rfbScreen->httpdDir to a directory containing vncviewer.jar and
index.vnc (like the included "classes" directory).
Hooks and IO functions
----------------------
TODO
Cursor handling
---------------
The rfbCursor structure consists mainly of a mask and a source. The mask
describes, which pixels are drawn for the cursor (a cursor needn't be
rectangular). The source describes, which colour those pixels should have.
The standard is an XCursor: a cursor with a foreground and a background
colour (stored in backRed and similar with a range from 0-0xffff). The
arrays "mask" and "source" consist of byte padded rows in MSB order (i.e. a
10x4 cursor's mask has 2x4 bytes, because 2 bytes are needed to hold 10 bits).
It is very easy to make a cursor like this:
char* cur=" "
" xx "
" x "
" ";
char* mask="xxxx"
"xxxx"
"xxxx"
"xxx ";
rfbCursorPtr c=rfbMakeXCursor(4,4,cur,mask);
You can even set "mask" to NULL in this call and LibVNCServer will calculate
a mask for you.
There is also an array named "richSource" for colourful cursors. They have
the same format as the frameBuffer.
History History
------- -------

20
TODO

@ -1,17 +1,15 @@
.cutpaste dont draw rich cursors as xcursors
test drawing of cursors when not using xcursor or rich cursor encoding
httpd
.other encodings
adapt rdp2vnc (rdesktop) adapt rdp2vnc (rdesktop)
udp udp
rfbCloseClient, rfbConnect, ConnectToTcpAddr rfbCloseClient, rfbConnect, ConnectToTcpAddr
CORBA CORBA
translate.c: warning about non 8-bit colourmaps translate.c: warning about non 8-bit colourmaps
cursors done:
.cursors
.cutpaste
.httpd
.other encodings

@ -24,11 +24,13 @@
#include <stdio.h> #include <stdio.h>
#include "rfb.h" #include "rfb.h"
#include "mipointer.h"
/*
#include "mipointer.h"
#include "sprite.h" #include "sprite.h"
#include "cursorstr.h" #include "cursorstr.h"
#include "servermd.h" #include "servermd.h"
*/
/* Copied from Xvnc/lib/font/util/utilbitmap.c */ /* Copied from Xvnc/lib/font/util/utilbitmap.c */
static unsigned char _reverse_byte[0x100] = { static unsigned char _reverse_byte[0x100] = {
@ -67,12 +69,12 @@ static unsigned char _reverse_byte[0x100] = {
}; };
static int EncodeRichCursorData8 (char *buf, rfbPixelFormat *fmt, static int EncodeRichCursorData8 (rfbClientPtr cl, char *buf, rfbPixelFormat *fmt,
CursorPtr pCursor); rfbCursorPtr pCursor);
static int EncodeRichCursorData16 (char *buf, rfbPixelFormat *fmt, static int EncodeRichCursorData16 (rfbClientPtr cl, char *buf, rfbPixelFormat *fmt,
CursorPtr pCursor); rfbCursorPtr pCursor);
static int EncodeRichCursorData32 (char *buf, rfbPixelFormat *fmt, static int EncodeRichCursorData32 (rfbClientPtr cl, char *buf, rfbPixelFormat *fmt,
CursorPtr pCursor); rfbCursorPtr pCursor);
/* /*
@ -80,45 +82,54 @@ static int EncodeRichCursorData32 (char *buf, rfbPixelFormat *fmt,
*/ */
Bool Bool
rfbSendCursorShape(cl, pScreen) rfbSendCursorShape(cl)
rfbClientPtr cl; rfbClientPtr cl;
ScreenPtr pScreen;
{ {
CursorPtr pCursor; rfbCursorPtr pCursor;
rfbFramebufferUpdateRectHeader rect; rfbFramebufferUpdateRectHeader rect;
rfbXCursorColors colors; rfbXCursorColors colors;
int saved_ublen; int saved_ublen;
int bitmapRowBytes, paddedRowBytes, maskBytes, dataBytes; int bitmapRowBytes, maskBytes, dataBytes;
int i, j; int i, j;
CARD8 *bitmapData; CARD8 *bitmapData;
CARD8 bitmapByte; CARD8 bitmapByte;
pCursor = cl->screen->getCursorPtr(cl);
if (cl->useRichCursorEncoding) { if (cl->useRichCursorEncoding) {
rect.encoding = Swap32IfLE(rfbEncodingRichCursor); if(!pCursor->richSource)
MakeRichCursorFromXCursor(cl->screen,pCursor);
rect.encoding = Swap32IfLE(rfbEncodingRichCursor);
} else { } else {
rect.encoding = Swap32IfLE(rfbEncodingXCursor); if(!pCursor->source)
MakeXCursorFromRichCursor(cl->screen,pCursor);
rect.encoding = Swap32IfLE(rfbEncodingXCursor);
} }
pCursor = rfbSpriteGetCursorPtr(pScreen); /*{
rfbScreenInfoPtr s=cl->screen;
SetXCutTextProcPtr sx=cl->screen->setXCutText;
GetCursorProcPtr g=cl->screen->getCursorPtr;
}*/
/* If there is no cursor, send update with empty cursor data. */ /* If there is no cursor, send update with empty cursor data. */
if ( pCursor->bits->width == 1 && if ( pCursor->width == 1 &&
pCursor->bits->height == 1 && pCursor->height == 1 &&
pCursor->bits->mask[0] == 0 ) { pCursor->mask[0] == 0 ) {
pCursor = NULL; pCursor = NULL;
} }
if (pCursor == NULL) { if (pCursor == NULL) {
if (ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE ) { if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE ) {
if (!rfbSendUpdateBuf(cl)) if (!rfbSendUpdateBuf(cl))
return FALSE; return FALSE;
} }
rect.r.x = rect.r.y = 0; rect.r.x = rect.r.y = 0;
rect.r.w = rect.r.h = 0; rect.r.w = rect.r.h = 0;
memcpy(&updateBuf[ublen], (char *)&rect, memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
sz_rfbFramebufferUpdateRectHeader); sz_rfbFramebufferUpdateRectHeader);
ublen += sz_rfbFramebufferUpdateRectHeader; cl->ublen += sz_rfbFramebufferUpdateRectHeader;
cl->rfbCursorBytesSent += sz_rfbFramebufferUpdateRectHeader; cl->rfbCursorBytesSent += sz_rfbFramebufferUpdateRectHeader;
cl->rfbCursorUpdatesSent++; cl->rfbCursorUpdatesSent++;
@ -131,37 +142,36 @@ rfbSendCursorShape(cl, pScreen)
/* Calculate data sizes. */ /* Calculate data sizes. */
bitmapRowBytes = (pCursor->bits->width + 7) / 8; bitmapRowBytes = (pCursor->width + 7) / 8;
paddedRowBytes = PixmapBytePad(pCursor->bits->width, 1); maskBytes = bitmapRowBytes * pCursor->height;
maskBytes = bitmapRowBytes * pCursor->bits->height;
dataBytes = (cl->useRichCursorEncoding) ? dataBytes = (cl->useRichCursorEncoding) ?
(pCursor->bits->width * pCursor->bits->height * (pCursor->width * pCursor->height *
(cl->format.bitsPerPixel / 8)) : maskBytes; (cl->format.bitsPerPixel / 8)) : maskBytes;
/* Send buffer contents if needed. */ /* Send buffer contents if needed. */
if ( ublen + sz_rfbFramebufferUpdateRectHeader + if ( cl->ublen + sz_rfbFramebufferUpdateRectHeader +
sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) { sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) {
if (!rfbSendUpdateBuf(cl)) if (!rfbSendUpdateBuf(cl))
return FALSE; return FALSE;
} }
if ( ublen + sz_rfbFramebufferUpdateRectHeader + if ( cl->ublen + sz_rfbFramebufferUpdateRectHeader +
sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) { sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) {
return FALSE; /* FIXME. */ return FALSE; /* FIXME. */
} }
saved_ublen = ublen; saved_ublen = cl->ublen;
/* Prepare rectangle header. */ /* Prepare rectangle header. */
rect.r.x = Swap16IfLE(pCursor->bits->xhot); rect.r.x = Swap16IfLE(pCursor->xhot);
rect.r.y = Swap16IfLE(pCursor->bits->yhot); rect.r.y = Swap16IfLE(pCursor->yhot);
rect.r.w = Swap16IfLE(pCursor->bits->width); rect.r.w = Swap16IfLE(pCursor->width);
rect.r.h = Swap16IfLE(pCursor->bits->height); rect.r.h = Swap16IfLE(pCursor->height);
memcpy(&updateBuf[ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader); memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader);
ublen += sz_rfbFramebufferUpdateRectHeader; cl->ublen += sz_rfbFramebufferUpdateRectHeader;
/* Prepare actual cursor data (depends on encoding used). */ /* Prepare actual cursor data (depends on encoding used). */
@ -174,57 +184,68 @@ rfbSendCursorShape(cl, pScreen)
colors.backGreen = (char)(pCursor->backGreen >> 8); colors.backGreen = (char)(pCursor->backGreen >> 8);
colors.backBlue = (char)(pCursor->backBlue >> 8); colors.backBlue = (char)(pCursor->backBlue >> 8);
memcpy(&updateBuf[ublen], (char *)&colors, sz_rfbXCursorColors); memcpy(&cl->updateBuf[cl->ublen], (char *)&colors, sz_rfbXCursorColors);
ublen += sz_rfbXCursorColors; cl->ublen += sz_rfbXCursorColors;
bitmapData = (CARD8 *)pCursor->bits->source; bitmapData = (CARD8 *)pCursor->source;
for (i = 0; i < pCursor->bits->height; i++) { for (i = 0; i < pCursor->height; i++) {
for (j = 0; j < bitmapRowBytes; j++) { for (j = 0; j < bitmapRowBytes; j++) {
bitmapByte = bitmapData[i * paddedRowBytes + j]; bitmapByte = bitmapData[i * bitmapRowBytes + j];
if (screenInfo.bitmapBitOrder == LSBFirst) { /*if (screenInfo.bitmapBitOrder == LSBFirst) {
bitmapByte = _reverse_byte[bitmapByte]; bitmapByte = _reverse_byte[bitmapByte];
} }*/
updateBuf[ublen++] = (char)bitmapByte; cl->updateBuf[cl->ublen++] = (char)bitmapByte;
} }
} }
} else { } else {
/* RichCursor encoding. */ /* RichCursor encoding. */
int bpp1=cl->screen->rfbServerFormat.bitsPerPixel/8,
bpp2=cl->format.bitsPerPixel/8;
(*cl->translateFn)(cl->translateLookupTable,
&(cl->screen->rfbServerFormat),
&cl->format, pCursor->richSource,
&cl->updateBuf[cl->ublen],
pCursor->width*bpp1, pCursor->width, pCursor->height);
cl->ublen += pCursor->width*bpp2*pCursor->height;
/*
switch (cl->format.bitsPerPixel) { switch (cl->format.bitsPerPixel) {
case 8: case 8:
ublen += EncodeRichCursorData8(&updateBuf[ublen], cl->ublen += EncodeRichCursorData8(cl, &cl->updateBuf[cl->ublen],
&cl->format, pCursor); &cl->format, pCursor);
break; break;
case 16: case 16:
ublen += EncodeRichCursorData16(&updateBuf[ublen], cl->ublen += EncodeRichCursorData16(cl, &cl->updateBuf[cl->ublen],
&cl->format, pCursor); &cl->format, pCursor);
break; break;
case 32: case 32:
ublen += EncodeRichCursorData32(&updateBuf[ublen], cl->ublen += EncodeRichCursorData32(cl, &cl->updateBuf[cl->ublen],
&cl->format, pCursor); &cl->format, pCursor);
break; break;
default: default:
return FALSE; return FALSE;
} }
*/
} }
/* Prepare transparency mask. */ /* Prepare transparency mask. */
bitmapData = (CARD8 *)pCursor->bits->mask; bitmapData = (CARD8 *)pCursor->mask;
for (i = 0; i < pCursor->bits->height; i++) { for (i = 0; i < pCursor->height; i++) {
for (j = 0; j < bitmapRowBytes; j++) { for (j = 0; j < bitmapRowBytes; j++) {
bitmapByte = bitmapData[i * paddedRowBytes + j]; bitmapByte = bitmapData[i * bitmapRowBytes + j];
if (screenInfo.bitmapBitOrder == LSBFirst) { /*if (screenInfo.bitmapBitOrder == LSBFirst) {
bitmapByte = _reverse_byte[bitmapByte]; bitmapByte = _reverse_byte[bitmapByte];
} }*/
updateBuf[ublen++] = (char)bitmapByte; cl->updateBuf[cl->ublen++] = (char)bitmapByte;
} }
} }
/* Send everything we have prepared in the updateBuf[]. */ /* Send everything we have prepared in the cl->updateBuf[]. */
cl->rfbCursorBytesSent += (ublen - saved_ublen); cl->rfbCursorBytesSent += (cl->ublen - saved_ublen);
cl->rfbCursorUpdatesSent++; cl->rfbCursorUpdatesSent++;
if (!rfbSendUpdateBuf(cl)) if (!rfbSendUpdateBuf(cl))
@ -244,10 +265,11 @@ rfbSendCursorShape(cl, pScreen)
((CARD32)(b) * ((fmt)->blueMax + 1) >> 16) << (fmt)->blueShift) ((CARD32)(b) * ((fmt)->blueMax + 1) >> 16) << (fmt)->blueShift)
static int static int
EncodeRichCursorData8(buf, fmt, pCursor) EncodeRichCursorData8(cl, buf, fmt, pCursor)
rfbClientPtr cl;
char *buf; char *buf;
rfbPixelFormat *fmt; rfbPixelFormat *fmt;
CursorPtr pCursor; rfbCursorPtr pCursor;
{ {
int widthPixels, widthBytes; int widthPixels, widthBytes;
int x, y, b; int x, y, b;
@ -260,41 +282,42 @@ EncodeRichCursorData8(buf, fmt, pCursor)
pix[1] = (char)RGB48_TO_PIXEL(fmt, pCursor->foreRed, pCursor->foreGreen, pix[1] = (char)RGB48_TO_PIXEL(fmt, pCursor->foreRed, pCursor->foreGreen,
pCursor->foreBlue); pCursor->foreBlue);
src = (CARD8 *)pCursor->bits->source; src = (CARD8 *)pCursor->richSource;
widthPixels = pCursor->bits->width; widthPixels = pCursor->width;
widthBytes = PixmapBytePad(widthPixels, 1); widthBytes = widthPixels;
for (y = 0; y < pCursor->bits->height; y++) { for (y = 0; y < pCursor->height; y++) {
for (x = 0; x < widthPixels / 8; x++) { for (x = 0; x < widthPixels / 8; x++) {
bitmapByte = src[y * widthBytes + x]; bitmapByte = src[y * widthBytes + x];
if (screenInfo.bitmapBitOrder == LSBFirst) { /*if (screenInfo.bitmapBitOrder == LSBFirst) {
bitmapByte = _reverse_byte[bitmapByte]; bitmapByte = _reverse_byte[bitmapByte];
} }*/
for (b = 7; b >= 0; b--) { for (b = 7; b >= 0; b--) {
*buf++ = pix[bitmapByte >> b & 1]; *buf++ = pix[bitmapByte >> b & 1];
} }
} }
if (widthPixels % 8) { if (widthPixels % 8) {
bitmapByte = src[y * widthBytes + x]; bitmapByte = src[y * widthBytes + x];
if (screenInfo.bitmapBitOrder == LSBFirst) { /*if (screenInfo.bitmapBitOrder == LSBFirst) {
bitmapByte = _reverse_byte[bitmapByte]; bitmapByte = _reverse_byte[bitmapByte];
} }*/
for (b = 7; b > 7 - widthPixels % 8; b--) { for (b = 7; b > 7 - widthPixels % 8; b--) {
*buf++ = pix[bitmapByte >> b & 1]; *buf++ = pix[bitmapByte >> b & 1];
} }
} }
} }
return (widthPixels * pCursor->bits->height); return (widthPixels * pCursor->height);
} }
#define DEFINE_RICH_ENCODE(bpp) \ #define DEFINE_RICH_ENCODE(bpp) \
\ \
static int \ static int \
EncodeRichCursorData##bpp(buf, fmt, pCursor) \ EncodeRichCursorData##bpp(cl, buf, fmt, pCursor) \
rfbClientPtr cl; \
char *buf; \ char *buf; \
rfbPixelFormat *fmt; \ rfbPixelFormat *fmt; \
CursorPtr pCursor; \ rfbCursorPtr pCursor; \
{ \ { \
int widthPixels, widthBytes; \ int widthPixels, widthBytes; \
int x, y, b; \ int x, y, b; \
@ -308,21 +331,21 @@ EncodeRichCursorData##bpp(buf, fmt, pCursor) \
pix[1] = (CARD##bpp)RGB48_TO_PIXEL(fmt, pCursor->foreRed, \ pix[1] = (CARD##bpp)RGB48_TO_PIXEL(fmt, pCursor->foreRed, \
pCursor->foreGreen, \ pCursor->foreGreen, \
pCursor->foreBlue); \ pCursor->foreBlue); \
if (!rfbServerFormat.bigEndian != !fmt->bigEndian) { \ if (!cl->screen->rfbServerFormat.bigEndian != !fmt->bigEndian) { \
pix[0] = Swap##bpp(pix[0]); \ pix[0] = Swap##bpp(pix[0]); \
pix[1] = Swap##bpp(pix[1]); \ pix[1] = Swap##bpp(pix[1]); \
} \ } \
\ \
src = (CARD8 *)pCursor->bits->source; \ src = (CARD8 *)pCursor->richSource; \
widthPixels = pCursor->bits->width; \ widthPixels = pCursor->width; \
widthBytes = PixmapBytePad(widthPixels, 1); \ widthBytes = (pCursor->width*bpp)/8; \
\ \
for (y = 0; y < pCursor->bits->height; y++) { \ for (y = 0; y < pCursor->height; y++) { \
for (x = 0; x < widthPixels / 8; x++) { \ for (x = 0; x < widthPixels / 8; x++) { \
bitmapByte = src[y * widthBytes + x]; \ bitmapByte = src[y * widthBytes + x]; \
if (screenInfo.bitmapBitOrder == LSBFirst) { \ /*if (screenInfo.bitmapBitOrder == LSBFirst) { \
bitmapByte = _reverse_byte[bitmapByte]; \ bitmapByte = _reverse_byte[bitmapByte]; \
} \ }*/ \
for (b = 7; b >= 0; b--) { \ for (b = 7; b >= 0; b--) { \
memcpy (buf, (char *)&pix[bitmapByte >> b & 1], \ memcpy (buf, (char *)&pix[bitmapByte >> b & 1], \
sizeof(CARD##bpp)); \ sizeof(CARD##bpp)); \
@ -331,9 +354,9 @@ EncodeRichCursorData##bpp(buf, fmt, pCursor) \
} \ } \
if (widthPixels % 8) { \ if (widthPixels % 8) { \
bitmapByte = src[y * widthBytes + x]; \ bitmapByte = src[y * widthBytes + x]; \
if (screenInfo.bitmapBitOrder == LSBFirst) { \ /*if (cl->screen.bitmapBitOrder == LSBFirst) { \
bitmapByte = _reverse_byte[bitmapByte]; \ bitmapByte = _reverse_byte[bitmapByte]; \
} \ }*/ \
for (b = 7; b > 7 - widthPixels % 8; b--) { \ for (b = 7; b > 7 - widthPixels % 8; b--) { \
memcpy (buf, (char *)&pix[bitmapByte >> b & 1], \ memcpy (buf, (char *)&pix[bitmapByte >> b & 1], \
sizeof(CARD##bpp)); \ sizeof(CARD##bpp)); \
@ -342,9 +365,208 @@ EncodeRichCursorData##bpp(buf, fmt, pCursor) \
} \ } \
} \ } \
\ \
return (widthPixels * pCursor->bits->height * (bpp / 8)); \ return (widthPixels * pCursor->height * (bpp / 8)); \
} }
DEFINE_RICH_ENCODE(16) DEFINE_RICH_ENCODE(16)
DEFINE_RICH_ENCODE(32) DEFINE_RICH_ENCODE(32)
void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap)
{
int i,t=(width+7)/8*height;
for(i=0;i<t;i++)
bitmap[i]=_reverse_byte[(int)bitmap[i]];
}
rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskString)
{
int i,j,w=(width+7)/8;
rfbCursorPtr cursor = (rfbCursorPtr)calloc(1,sizeof(rfbCursor));
char* cp;
unsigned char bit;
cursor->width=width;
cursor->height=height;
//cursor->backRed=cursor->backGreen=cursor->backBlue=0xffff;
cursor->foreRed=cursor->foreGreen=cursor->foreBlue=0xffff;
cursor->source = (char*)calloc(w,height);
for(j=0,cp=cursorString;j<height;j++)
for(i=0,bit=0x80;i<width;i++,bit=(bit&1)?0x80:bit>>1,cp++)
if(*cp!=' ') cursor->source[j*w+i/8]|=bit;
if(maskString) {
cursor->mask = (char*)calloc(w,height);
for(j=0,cp=maskString;j<height;j++)
for(i=0,bit=0x80;i<width;i++,bit=(bit&1)?0x80:bit>>1,cp++)
if(*cp!=' ') cursor->mask[j*w+i/8]|=bit;
} else
cursor->mask = rfbMakeMaskForXCursor(width,height,cursor->source);
return(cursor);
}
char* rfbMakeMaskForXCursor(int width,int height,char* source)
{
int i,j,w=(width+7)/8;
char* mask=(char*)calloc(w,height);
unsigned char c;
for(j=0;j<height;j++)
for(i=w-1;i>=0;i--) {
c=source[j*w+i];
if(j>0) c|=source[(j-1)*w+i];
if(j<height-1) c|=source[(j+1)*w+i];
if(i>0 && (c&0x80))
mask[j*w+i-1]|=0x01;
if(i<w-1 && (c&0x01))
mask[j*w+i+1]|=0x80;
mask[j*w+i]|=(c<<1)|c|(c>>1);
}
return(mask);
}
void rfbFreeCursor(rfbCursorPtr cursor)
{
if(cursor) {
free(cursor->source);
free(cursor->mask);
free(cursor);
}
}
/* background and foregroud colour have to be set beforehand */
void MakeXCursorFromRichCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor)
{
rfbPixelFormat* format=&rfbScreen->rfbServerFormat;
int i,j,w=(cursor->width+7)/8,bpp=format->bitsPerPixel/8,
width=cursor->width*bpp;
CARD32 background;
char *back=(char*)&background;
unsigned char bit;
cursor->source=(char*)calloc(w,cursor->height);
if(format->bigEndian)
back+=4-bpp;
background=cursor->backRed<<format->redShift|
cursor->backGreen<<format->greenShift|cursor->backBlue<<format->blueShift;
for(j=0;j<cursor->height;j++)
for(i=0,bit=0x80;i<cursor->width;i++,bit=(bit&1)?0x80:bit>>1)
if(memcmp(cursor->richSource+j*width+i*bpp,back,bpp))
cursor->source[j*w+i/8]|=bit;
}
void MakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor)
{
rfbPixelFormat* format=&rfbScreen->rfbServerFormat;
int i,j,w=(cursor->width+7)/8,bpp=format->bitsPerPixel/8;
CARD32 background,foreground;
char *cp,*back=(char*)&background,*fore=(char*)&foreground;
unsigned char bit;
cp=cursor->richSource=(char*)calloc(cursor->width*bpp,cursor->height);
if(format->bigEndian) {
back+=4-bpp;
fore+=4-bpp;
}
background=cursor->backRed<<format->redShift|
cursor->backGreen<<format->greenShift|cursor->backBlue<<format->blueShift;
foreground=cursor->foreRed<<format->redShift|
cursor->foreGreen<<format->greenShift|cursor->foreBlue<<format->blueShift;
for(j=0;j<cursor->height;j++)
for(i=0,bit=0x80;i<cursor->height;i++,bit=(bit&1)?0x80:bit>>1,cp+=bpp)
if(cursor->source[j*w+i/8]&bit) memcpy(cp,fore,bpp);
else memcpy(cp,back,bpp);
}
void rfbUndrawCursor(rfbClientPtr cl)
{
rfbScreenInfoPtr s=cl->screen;
rfbCursorPtr c=s->cursor;
int j,x1,x2,y1,y2,bpp=s->rfbServerFormat.bitsPerPixel/8,
rowstride=s->paddedWidthInBytes;
if(!s->cursorIsDrawn)
return;
/* restore what is under the cursor */
x1=s->cursorX-c->xhot;
x2=x1+c->width;
if(x1<0) x1=0;
if(x2>=s->width) x2=s->width-1;
x2-=x1;
y1=s->cursorY-c->yhot;
y2=y1+c->height;
if(y1<0) y1=0;
if(y2>=s->height) y2=s->height-1;
y2-=y1;
for(j=0;j<y2;j++)
memcpy(s->frameBuffer+(y1+j)*rowstride+x1*bpp,
s->underCursorBuffer+j*x2*bpp,
x2*bpp);
}
void rfbDrawCursor(rfbClientPtr cl)
{
rfbScreenInfoPtr s=cl->screen;
rfbCursorPtr c=s->cursor;
int i,j,x1,x2,y1,y2,i1,j1,bpp=s->rfbServerFormat.bitsPerPixel/8,
rowstride=s->paddedWidthInBytes,
bufSize=c->width*c->height*bpp,w=(c->width+7)/8;
if(s->cursorIsDrawn)
rfbUndrawCursor(cl);
if(s->underCursorBufferLen<bufSize) {
if(s->underCursorBuffer!=NULL)
free(s->underCursorBuffer);
s->underCursorBuffer=malloc(bufSize);
s->underCursorBufferLen=bufSize;
}
/* save what is under the cursor */
i1=j1=0; /* offset in cursor */
x1=s->cursorX-c->xhot;
x2=x1+c->width;
if(x1<0) { i1=-x1; x1=0; }
if(x2>=s->width) x2=s->width-1;
x2-=x1;
y1=s->cursorY-c->yhot;
y2=y1+c->height;
if(y1<0) { j1=-y1; y1=0; }
if(y2>=s->height) y2=s->height-1;
y2-=y1;
for(j=0;j<y2;j++)
memcpy(s->underCursorBuffer+j*x2*bpp,
s->frameBuffer+(y1+j)*rowstride+x1*bpp,
x2*bpp);
if(!c->richSource)
MakeRichCursorFromXCursor(s,c);
/* now the cursor has to be drawn */
for(j=0;j<y2;j++)
for(i=0;i<x2;i++)
if((c->mask[(j+j1)*w+(i+i1)/8]<<((i+i1)&7))&0x80)
memcpy(s->frameBuffer+(j+y1)*rowstride+(i+x1)*bpp,
c->richSource+(j+j1)*c->width*bpp+(i+i1)*bpp,bpp);
}
void rfbPrintXCursor(rfbCursorPtr cursor)
{
int i,i1,j,w=(cursor->width+7)/8;
unsigned char bit;
for(j=0;j<cursor->height;j++) {
for(i=0,i1=0,bit=0x80;i1<cursor->width;i1++,i+=(bit&1)?1:0,bit=(bit&1)?0x80:bit>>1)
if(cursor->source[j*w+i]&bit) putchar('#'); else putchar(' ');
putchar(':');
for(i=0,i1=0,bit=0x80;i1<cursor->width;i1++,i+=(bit&1)?1:0,bit=(bit&1)?0x80:bit>>1)
if(cursor->mask[j*w+i]&bit) putchar('#'); else putchar(' ');
putchar('\n');
}
}

@ -68,6 +68,11 @@ void drawline(unsigned char* buffer,int rowstride,int bpp,int x1,int y1,int x2,i
{ {
int i,j; int i,j;
i=x1-x2; j=y1-y2; i=x1-x2; j=y1-y2;
if(i==0 && j==0) {
for(i=0;i<bpp;i++)
buffer[y1*rowstride+x1*bpp+i]=0xff;
return;
}
if(i<0) i=-i; if(i<0) i=-i;
if(j<0) j=-j; if(j<0) j=-j;
if(i<j) { if(i<j) {
@ -89,32 +94,34 @@ void drawline(unsigned char* buffer,int rowstride,int bpp,int x1,int y1,int x2,i
void doptr(int buttonMask,int x,int y,rfbClientPtr cl) void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
{ {
ClientData* cd=cl->clientData; ClientData* cd=cl->clientData;
if(buttonMask && x>=0 && y>=0 && x<maxx && y<maxy) { if(x>=0 && y>=0 && x<maxx && y<maxy) {
int i,j,x1,x2,y1,y2; if(buttonMask) {
int i,j,x1,x2,y1,y2;
if(cd->oldButton==buttonMask) { /* draw a line */
drawline(cl->screen->frameBuffer,cl->screen->paddedWidthInBytes,bpp, if(cd->oldButton==buttonMask) { /* draw a line */
x,y,cd->oldx,cd->oldy); drawline(cl->screen->frameBuffer,cl->screen->paddedWidthInBytes,bpp,
rfbMarkRectAsModified(cl->screen,x,y,cd->oldx,cd->oldy); x,y,cd->oldx,cd->oldy);
} else { /* draw a point (diameter depends on button) */ rfbMarkRectAsModified(cl->screen,x,y,cd->oldx,cd->oldy);
x1=x-buttonMask; if(x1<0) x1=0; } else { /* draw a point (diameter depends on button) */
x2=x+buttonMask; if(x2>maxx) x2=maxx; x1=x-buttonMask; if(x1<0) x1=0;
y1=y-buttonMask; if(y1<0) y1=0; x2=x+buttonMask; if(x2>maxx) x2=maxx;
y2=y+buttonMask; if(y2>maxy) y2=maxy; y1=y-buttonMask; if(y1<0) y1=0;
y2=y+buttonMask; if(y2>maxy) y2=maxy;
for(i=x1*bpp;i<x2*bpp;i++)
for(j=y1;j<y2;j++)
cl->screen->frameBuffer[j*cl->screen->paddedWidthInBytes+i]=0xff;
rfbMarkRectAsModified(cl->screen,x1,y1,x2-1,y2-1);
}
/* we could get a selection like that: for(i=x1*bpp;i<x2*bpp;i++)
rfbGotXCutText(cl->screen,"Hallo",5); for(j=y1;j<y2;j++)
*/ cl->screen->frameBuffer[j*cl->screen->paddedWidthInBytes+i]=0xff;
} else rfbMarkRectAsModified(cl->screen,x1,y1,x2-1,y2-1);
cd->oldButton=0; }
cd->oldx=x; cd->oldy=y; cd->oldButton=buttonMask; /* we could get a selection like that:
rfbGotXCutText(cl->screen,"Hallo",5);
*/
} else
cd->oldButton=0;
cd->oldx=x; cd->oldy=y; cd->oldButton=buttonMask;
}
} }
/* aux function to draw a character to x, y */ /* aux function to draw a character to x, y */
@ -196,6 +203,24 @@ void dokey(Bool down,KeySym key,rfbClientPtr cl)
} }
} }
/*
extern void rfbPrintXCursor(rfbCursorPtr cursor);
int exampleCursorWidth=9,exampleCursorHeight=7;
char exampleCursor[]=
" "
" xx xx "
" xx xx "
" xxx "
" xx xx "
" xx xx "
" ";
rfbCursorPtr exampleCurse;
rfbCursorPtr exampleGetCursor(rfbClientPtr cl)
{
return(exampleCurse);
}
*/
/* Initialization */ /* Initialization */
int main(int argc,char** argv) int main(int argc,char** argv)
@ -211,8 +236,31 @@ int main(int argc,char** argv)
rfbScreen->httpDir = "./classes"; rfbScreen->httpDir = "./classes";
initBuffer(rfbScreen->frameBuffer); initBuffer(rfbScreen->frameBuffer);
drawstring(rfbScreen->frameBuffer,maxx*bpp,bpp,20,100,"Hello, World!");
drawstring(rfbScreen->frameBuffer,maxx*bpp,bpp,20,100,"Hallo, Welt!"); //exampleCurse = rfbMakeXCursor(exampleCursorWidth,exampleCursorHeight,exampleCursor,0);
{
int i,j,w=32,h=32;
rfbCursorPtr c = rfbScreen->cursor;
char x[32*32],mask[32*32/8];
c=rfbScreen->cursor = rfbMakeXCursor(w,h,x,mask);
c->mask[0]=0xff; c->mask[1]=0x0;
memset(c->mask,255,h*w/8);
c->richSource = malloc(w*h*bpp);
for(j=0;j<h;j++) {
for(i=0;i<w;i++) {
c->richSource[j*w*bpp+i*bpp+0]=0;
c->richSource[j*w*bpp+i*bpp+1]=0;
c->richSource[j*w*bpp+i*bpp+2]=j*0xff/h;
c->richSource[j*w*bpp+i*bpp+3]=0;
}
c->richSource[j*w*bpp+(w-1)*bpp+0]=0xff;
c->richSource[j*w*bpp+(w-1)*bpp+1]=0xff;
c->richSource[j*w*bpp+(w-1)*bpp+2]=0xff;
c->richSource[j*w*bpp+(w-1)*bpp+3]=0xff;
}
//memset(c->richSource,0xff,w*h*bpp);
}
/* this is the blocking event loop, i.e. it never returns */ /* this is the blocking event loop, i.e. it never returns */
/* 40000 are the microseconds, i.e. 0.04 seconds */ /* 40000 are the microseconds, i.e. 0.04 seconds */

@ -31,6 +31,8 @@
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <pwd.h> #include <pwd.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "rfb.h" #include "rfb.h"
@ -99,7 +101,7 @@ httpInitSockets(rfbScreenInfoPtr rfbScreen)
void void
httpCheckFds(rfbScreenInfoPtr rfbScreen) httpCheckFds(rfbScreenInfoPtr rfbScreen)
{ {
int nfds, n; int nfds;
fd_set fds; fd_set fds;
struct timeval tv; struct timeval tv;
struct sockaddr_in addr; struct sockaddr_in addr;

@ -37,6 +37,7 @@
#endif #endif
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <time.h>
#include "rfb.h" #include "rfb.h"
@ -93,8 +94,16 @@ void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y
RegionRec region; RegionRec region;
int i; int i;
if(x1>x2) { i=x1; x1=x2; x2=i; } if(x1>x2) { i=x1; x1=x2; x2=i; }
x2++;
if(x1<0) { x1=0; if(x2==x1) x2++; }
if(x2>=rfbScreen->width) { x2=rfbScreen->width-1; if(x1==x2) x1--; }
if(y1>y2) { i=y1; y1=y2; y2=i; } if(y1>y2) { i=y1; y1=y2; y2=i; }
box.x1=x1; box.y1=y1; box.x2=x2+1; box.y2=y2+1; y2++;
if(y1<0) { y1=0; if(y2==y1) y2++; }
if(y2>=rfbScreen->height) { y2=rfbScreen->height-1; if(y1==y2) y1--; }
box.x1=x1; box.y1=y1; box.x2=x2; box.y2=y2;
REGION_INIT(cl->screen,&region,&box,0); REGION_INIT(cl->screen,&region,&box,0);
rfbMarkRegionAsModified(rfbScreen,&region); rfbMarkRegionAsModified(rfbScreen,&region);
} }
@ -295,6 +304,38 @@ void defaultSetXCutText(char* text, int len, rfbClientPtr cl)
{ {
} }
static rfbCursor myCursor =
{
//width: 8, height: 7, xhot: 3, yhot: 3,
width: 8, height: 7, xhot: 0, yhot: 0,
//source: "\000\102\044\030\044\102\000",
//mask: "\347\347\176\074\176\347\347",
source: "\000\074\176\146\176\074\000",
mask: "\176\377\377\377\377\377\176",
foreRed: 0, foreGreen: 0, foreBlue: 0,
backRed: 0xffff, backGreen: 0xffff, backBlue: 0xffff,
#define D "\000\000\000\000"
#define R "\377\000\000\000"
#define G "\000\377\000\000"
#define B "\000\000\377\000"
#define S "\377\377\000\000"
#define H "\000\377\377\000"
#define C "\377\000\377\000"
richSource: 0
/*D D D D D D D D
D D R R R R D D
D S S S S S S D
D G G D D G G D
D H H H H H H D
D D B B B B D D
D D D D D D D D*/
};
rfbCursorPtr defaultGetCursorPtr(rfbClientPtr cl)
{
return(cl->screen->cursor);
}
void doNothingWithClient(rfbClientPtr cl) void doNothingWithClient(rfbClientPtr cl)
{ {
} }
@ -348,15 +389,12 @@ rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv,int width,int height,
rfbScreen->rfbServerFormat.redShift = bitsPerSample * 2; rfbScreen->rfbServerFormat.redShift = bitsPerSample * 2;
rfbScreen->rfbServerFormat.greenShift = bitsPerSample; rfbScreen->rfbServerFormat.greenShift = bitsPerSample;
rfbScreen->rfbServerFormat.blueShift = 0; rfbScreen->rfbServerFormat.blueShift = 0;
fprintf(stderr,"format: %d %d %d %d %d %d\n",
rfbScreen->rfbServerFormat.redMax,
rfbScreen->rfbServerFormat.greenMax,
rfbScreen->rfbServerFormat.blueMax,
rfbScreen->rfbServerFormat.redShift,
rfbScreen->rfbServerFormat.greenShift,
rfbScreen->rfbServerFormat.blueShift);
rfbScreen->cursorIsDrawn = FALSE;
rfbScreen->dontSendFramebufferUpdate = FALSE;
rfbScreen->cursorX=rfbScreen->cursorY=rfbScreen->underCursorBufferLen=0;
rfbScreen->underCursorBuffer=NULL;
/* We want to use the X11 REGION_* macros without having an actual /* We want to use the X11 REGION_* macros without having an actual
X11 ScreenPtr, so we do this. Pretty ugly, but at least it lets us X11 ScreenPtr, so we do this. Pretty ugly, but at least it lets us
avoid hacking up regionstr.h, or changing every call to REGION_* avoid hacking up regionstr.h, or changing every call to REGION_*
@ -384,6 +422,8 @@ fprintf(stderr,"format: %d %d %d %d %d %d\n",
rfbScreen->kbdReleaseAllKeys = doNothingWithClient; rfbScreen->kbdReleaseAllKeys = doNothingWithClient;
rfbScreen->ptrAddEvent = defaultPtrAddEvent; rfbScreen->ptrAddEvent = defaultPtrAddEvent;
rfbScreen->setXCutText = defaultSetXCutText; rfbScreen->setXCutText = defaultSetXCutText;
rfbScreen->getCursorPtr = defaultGetCursorPtr;
rfbScreen->cursor = &myCursor;
rfbScreen->newClientHook = doNothingWithClient; rfbScreen->newClientHook = doNothingWithClient;
return(rfbScreen); return(rfbScreen);

38
rfb.h

@ -23,6 +23,8 @@
* USA. * USA.
*/ */
#include <stdlib.h>
#include <string.h>
#include "scrnintstr.h" #include "scrnintstr.h"
/* trying to replace the above with some more minimal set of includes */ /* trying to replace the above with some more minimal set of includes */
@ -60,12 +62,14 @@
#endif #endif
struct rfbClientRec; struct rfbClientRec;
//typedef struct rfbClientInfo* rfbClientPtr; struct rfbScreenInfo;
struct rfbCursor;
typedef void (*KbdAddEventProcPtr) (Bool down, KeySym keySym, struct rfbClientRec* cl); typedef void (*KbdAddEventProcPtr) (Bool down, KeySym keySym, struct rfbClientRec* cl);
typedef void (*KbdReleaseAllKeysProcPtr) (struct rfbClientRec* cl); typedef void (*KbdReleaseAllKeysProcPtr) (struct rfbClientRec* cl);
typedef void (*PtrAddEventProcPtr) (int buttonMask, int x, int y, struct rfbClientRec* cl); typedef void (*PtrAddEventProcPtr) (int buttonMask, int x, int y, struct rfbClientRec* cl);
typedef void (*SetXCutTextProcPtr) (char* str,int len, struct rfbClientRec* cl); typedef void (*SetXCutTextProcPtr) (char* str,int len, struct rfbClientRec* cl);
typedef struct rfbCursor* (*GetCursorProcPtr) (struct rfbClientRec* pScreen);
typedef void (*NewClientHookPtr)(struct rfbClientRec* cl); typedef void (*NewClientHookPtr)(struct rfbClientRec* cl);
/* /*
@ -125,7 +129,11 @@ typedef struct
Bool cursorIsDrawn; /* TRUE if the cursor is currently drawn */ Bool cursorIsDrawn; /* TRUE if the cursor is currently drawn */
Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the Bool dontSendFramebufferUpdate; /* TRUE while removing or drawing the
cursor */ cursor */
/* these variables are needed to save the area under the cursor */
int cursorX, cursorY,underCursorBufferLen;
char* underCursorBuffer;
/* wrapped screen functions */ /* wrapped screen functions */
CloseScreenProcPtr CloseScreen; CloseScreenProcPtr CloseScreen;
@ -167,14 +175,16 @@ typedef struct
Bool rfbNeverShared; Bool rfbNeverShared;
Bool rfbDontDisconnect; Bool rfbDontDisconnect;
struct rfbClientRec* rfbClientHead; struct rfbClientRec* rfbClientHead;
struct rfbCursor* cursor;
/* the following members have to be supplied by the serving process */ /* the following members have to be supplied by the serving process */
char* frameBuffer; char* frameBuffer;
KbdAddEventProcPtr kbdAddEvent; KbdAddEventProcPtr kbdAddEvent;
KbdReleaseAllKeysProcPtr kbdReleaseAllKeys; KbdReleaseAllKeysProcPtr kbdReleaseAllKeys;
PtrAddEventProcPtr ptrAddEvent; PtrAddEventProcPtr ptrAddEvent;
SetXCutTextProcPtr setXCutText; SetXCutTextProcPtr setXCutText;
GetCursorProcPtr getCursorPtr;
/* the following members are hooks, i.e. they are called if set, /* the following members are hooks, i.e. they are called if set,
but not overriding original functionality */ but not overriding original functionality */
/* newClientHook is called just after a new client is created */ /* newClientHook is called just after a new client is created */
@ -513,8 +523,22 @@ extern Bool rfbSendRectEncodingTight(rfbClientPtr cl, int x,int y,int w,int h);
/* cursor.c */ /* cursor.c */
extern Bool rfbSendCursorShape(rfbClientPtr cl, ScreenPtr pScreen); typedef struct rfbCursor {
unsigned char *source; /* points to bits */
unsigned char *mask; /* points to bits */
unsigned short width, height, xhot, yhot; /* metrics */
unsigned short foreRed, foreGreen, foreBlue; /* device-independent color */
unsigned short backRed, backGreen, backBlue; /* device-independent color */
unsigned char *richSource; /* source bytes for a rich cursor */
} rfbCursor, *rfbCursorPtr;
extern Bool rfbSendCursorShape(rfbClientPtr cl/*, rfbScreenInfoPtr pScreen*/);
extern void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap);
extern rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskString);
extern char* rfbMakeMaskForXCursor(int width,int height,char* cursorString);
extern void MakeXCursorFromRichCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor);
extern void MakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor);
extern void rfbFreeCursor(rfbCursorPtr cursor);
/* stats.c */ /* stats.c */

@ -221,6 +221,7 @@ rfbNewClient(rfbScreen,sock)
cl->zsActive[i] = FALSE; cl->zsActive[i] = FALSE;
cl->enableCursorShapeUpdates = FALSE; cl->enableCursorShapeUpdates = FALSE;
cl->useRichCursorEncoding = FALSE;
cl->enableLastRectEncoding = FALSE; cl->enableLastRectEncoding = FALSE;
rfbResetStats(cl); rfbResetStats(cl);
@ -630,18 +631,15 @@ rfbProcessClientNormalMessage(cl)
rfbLog("Enabling X-style cursor updates for client %s\n", rfbLog("Enabling X-style cursor updates for client %s\n",
cl->host); cl->host);
cl->enableCursorShapeUpdates = TRUE; cl->enableCursorShapeUpdates = TRUE;
cl->useRichCursorEncoding = FALSE;
cl->cursorWasChanged = TRUE; cl->cursorWasChanged = TRUE;
break; break;
case rfbEncodingRichCursor: case rfbEncodingRichCursor:
if (!cl->enableCursorShapeUpdates) { rfbLog("Enabling full-color cursor updates for client "
rfbLog("Enabling full-color cursor updates for client " "%s\n", cl->host);
"%s\n", cl->host); cl->enableCursorShapeUpdates = TRUE;
cl->enableCursorShapeUpdates = TRUE; cl->useRichCursorEncoding = TRUE;
cl->useRichCursorEncoding = TRUE; cl->cursorWasChanged = TRUE;
cl->cursorWasChanged = TRUE; break;
}
break;
case rfbEncodingLastRect: case rfbEncodingLastRect:
if (!cl->enableLastRectEncoding) { if (!cl->enableLastRectEncoding) {
rfbLog("Enabling LastRect protocol extension for client " rfbLog("Enabling LastRect protocol extension for client "
@ -829,23 +827,24 @@ rfbSendFramebufferUpdate(cl, updateRegion)
RegionRec updateCopyRegion; RegionRec updateCopyRegion;
int dx, dy; int dx, dy;
Bool sendCursorShape = FALSE; Bool sendCursorShape = FALSE;
Bool cursorWasDrawn = FALSE;
/* /*
* If this client understands cursor shape updates, cursor should be * If this client understands cursor shape updates, cursor should be
* removed from the framebuffer. Otherwise, make sure it's put up. * removed from the framebuffer. Otherwise, make sure it's put up.
*/ */
#ifdef NOT_YET
if (cl->enableCursorShapeUpdates) { if (cl->enableCursorShapeUpdates) {
if (cl->screen->cursorIsDrawn) cursorWasDrawn = cl->screen->cursorIsDrawn;
rfbSpriteRemoveCursor(pScreen); if (cl->screen->cursorIsDrawn) {
if (!cl->screen->cursorIsDrawn && cl->cursorWasChanged) fprintf(stderr,"rfbSpriteRemoveCursor(pScreen); not yet!\n");
sendCursorShape = TRUE; }
if (!cl->screen->cursorIsDrawn && cl->cursorWasChanged)
sendCursorShape = TRUE;
} else { } else {
if (!cl->screen->cursorIsDrawn) if (!cl->screen->cursorIsDrawn)
rfbSpriteRestoreCursor(pScreen); fprintf(stderr,"rfbSpriteRestoreCursor(pScreen); not yet!\n");
} }
#endif
/* /*
* The modifiedRegion may overlap the destination copyRegion. We remove * The modifiedRegion may overlap the destination copyRegion. We remove
@ -976,13 +975,11 @@ rfbSendFramebufferUpdate(cl, updateRegion)
} }
cl->ublen = sz_rfbFramebufferUpdateMsg; cl->ublen = sz_rfbFramebufferUpdateMsg;
#ifdef NOT_YET
if (sendCursorShape) { if (sendCursorShape) {
cl->cursorWasChanged = FALSE; cl->cursorWasChanged = FALSE;
if (!rfbSendCursorShape(cl, pScreen)) if (!rfbSendCursorShape(cl))
return FALSE; return FALSE;
} }
#endif
if (REGION_NOTEMPTY(pScreen,&updateCopyRegion)) { if (REGION_NOTEMPTY(pScreen,&updateCopyRegion)) {
if (!rfbSendCopyRegion(cl,&updateCopyRegion,dx,dy)) { if (!rfbSendCopyRegion(cl,&updateCopyRegion,dx,dy)) {
@ -1047,6 +1044,13 @@ rfbSendFramebufferUpdate(cl, updateRegion)
if (!rfbSendUpdateBuf(cl)) if (!rfbSendUpdateBuf(cl))
return FALSE; return FALSE;
if(cursorWasDrawn != cl->screen->cursorIsDrawn) {
if(cursorWasDrawn)
fprintf(stderr,"rfbSpriteRestoreCursor(pScreen); not yet!!\n");
else
fprintf(stderr,"rfbSpriteRemoveCursor(pScreen); not yet!!\n");
}
return TRUE; return TRUE;
} }

@ -57,6 +57,7 @@ struct timeval
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <arpa/inet.h>
#include "rfb.h" #include "rfb.h"

@ -235,8 +235,6 @@ rfbSendRectEncodingZlib(cl, x, y, w, h)
rfbClientPtr cl; rfbClientPtr cl;
int x, y, w, h; int x, y, w, h;
{ {
int totalSize = 0;
int partialSize = 0;
int maxLines; int maxLines;
int linesRemaining; int linesRemaining;
rfbRectangle partialRect; rfbRectangle partialRect;

Loading…
Cancel
Save