From 5c438e3fb2d98f6aa36b58610ed9d871a41cf6f1 Mon Sep 17 00:00:00 2001 From: dscho Date: Mon, 24 Sep 2001 22:02:28 +0000 Subject: [PATCH] bugfix: cursor (works now without xcursor encoding) --- Makefile | 3 +- TODO | 6 +- cursor.c | 146 +------------------------------------------ example.c | 12 ++-- include/Xserver/os.h | 4 +- main.c | 3 + miregion.c | 15 +++-- pnmshow.c | 17 +++-- rfb.h | 78 ++++++++++++++++++++--- rfbserver.c | 11 ++-- sockets.c | 2 + xalloc.c | 10 +-- 12 files changed, 126 insertions(+), 181 deletions(-) diff --git a/Makefile b/Makefile index d5ed14c..498e106 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,8 @@ CFLAGS=-g -Wall #CFLAGS=-O2 -Wall RANLIB=ranlib -INCLUDES=-I. -Ilibvncauth -Iinclude -Iinclude/X11 -Iinclude/Xserver +INCLUDES=-I. -Ilibvncauth -Iinclude +# -Iinclude/X11 -Iinclude/Xserver VNCAUTHLIB=-Llibvncauth -lvncauth VNCSERVERLIB=-L. -lvncserver -lz -ljpeg diff --git a/TODO b/TODO index a7d0b14..2f6cf54 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,11 @@ -dont draw rich cursors as xcursors -test drawing of cursors when not using xcursor or rich cursor encoding +fix bug with odd width adapt rdp2vnc (rdesktop) +dont draw rich cursors as xcursors udp rfbCloseClient, rfbConnect, ConnectToTcpAddr CORBA translate.c: warning about non 8-bit colourmaps +set colourmap done: @@ -12,4 +13,5 @@ done: .cutpaste .httpd .other encodings +.test drawing of cursors when not using xcursor or rich cursor encoding diff --git a/cursor.c b/cursor.c index d128254..bada62b 100644 --- a/cursor.c +++ b/cursor.c @@ -69,14 +69,6 @@ static unsigned char _reverse_byte[0x100] = { }; -static int EncodeRichCursorData8 (rfbClientPtr cl, char *buf, rfbPixelFormat *fmt, - rfbCursorPtr pCursor); -static int EncodeRichCursorData16 (rfbClientPtr cl, char *buf, rfbPixelFormat *fmt, - rfbCursorPtr pCursor); -static int EncodeRichCursorData32 (rfbClientPtr cl, char *buf, rfbPixelFormat *fmt, - rfbCursorPtr pCursor); - - /* * Send cursor shape either in X-style format or in client pixel format. */ @@ -209,24 +201,6 @@ rfbSendCursorShape(cl) pCursor->width*bpp1, pCursor->width, pCursor->height); cl->ublen += pCursor->width*bpp2*pCursor->height; - /* - switch (cl->format.bitsPerPixel) { - case 8: - cl->ublen += EncodeRichCursorData8(cl, &cl->updateBuf[cl->ublen], - &cl->format, pCursor); - break; - case 16: - cl->ublen += EncodeRichCursorData16(cl, &cl->updateBuf[cl->ublen], - &cl->format, pCursor); - break; - case 32: - cl->ublen += EncodeRichCursorData32(cl, &cl->updateBuf[cl->ublen], - &cl->format, pCursor); - break; - default: - return FALSE; - } - */ } /* Prepare transparency mask. */ @@ -254,123 +228,7 @@ rfbSendCursorShape(cl) return TRUE; } - -/* - * Code to convert cursor source bitmap to the desired pixel format. - */ - -#define RGB48_TO_PIXEL(fmt,r,g,b) \ - (((CARD32)(r) * ((fmt)->redMax + 1) >> 16) << (fmt)->redShift | \ - ((CARD32)(g) * ((fmt)->greenMax + 1) >> 16) << (fmt)->greenShift | \ - ((CARD32)(b) * ((fmt)->blueMax + 1) >> 16) << (fmt)->blueShift) - -static int -EncodeRichCursorData8(cl, buf, fmt, pCursor) - rfbClientPtr cl; - char *buf; - rfbPixelFormat *fmt; - rfbCursorPtr pCursor; -{ - int widthPixels, widthBytes; - int x, y, b; - CARD8 *src; - char pix[2]; - CARD8 bitmapByte; - - pix[0] = (char)RGB48_TO_PIXEL(fmt, pCursor->backRed, pCursor->backGreen, - pCursor->backBlue); - pix[1] = (char)RGB48_TO_PIXEL(fmt, pCursor->foreRed, pCursor->foreGreen, - pCursor->foreBlue); - - src = (CARD8 *)pCursor->richSource; - widthPixels = pCursor->width; - widthBytes = widthPixels; - - for (y = 0; y < pCursor->height; y++) { - for (x = 0; x < widthPixels / 8; x++) { - bitmapByte = src[y * widthBytes + x]; - /*if (screenInfo.bitmapBitOrder == LSBFirst) { - bitmapByte = _reverse_byte[bitmapByte]; - }*/ - for (b = 7; b >= 0; b--) { - *buf++ = pix[bitmapByte >> b & 1]; - } - } - if (widthPixels % 8) { - bitmapByte = src[y * widthBytes + x]; - /*if (screenInfo.bitmapBitOrder == LSBFirst) { - bitmapByte = _reverse_byte[bitmapByte]; - }*/ - for (b = 7; b > 7 - widthPixels % 8; b--) { - *buf++ = pix[bitmapByte >> b & 1]; - } - } - } - - return (widthPixels * pCursor->height); -} - -#define DEFINE_RICH_ENCODE(bpp) \ - \ -static int \ -EncodeRichCursorData##bpp(cl, buf, fmt, pCursor) \ - rfbClientPtr cl; \ - char *buf; \ - rfbPixelFormat *fmt; \ - rfbCursorPtr pCursor; \ -{ \ - int widthPixels, widthBytes; \ - int x, y, b; \ - CARD8 *src; \ - CARD##bpp pix[2]; \ - CARD8 bitmapByte; \ - \ - pix[0] = (CARD##bpp)RGB48_TO_PIXEL(fmt, pCursor->backRed, \ - pCursor->backGreen, \ - pCursor->backBlue); \ - pix[1] = (CARD##bpp)RGB48_TO_PIXEL(fmt, pCursor->foreRed, \ - pCursor->foreGreen, \ - pCursor->foreBlue); \ - if (!cl->screen->rfbServerFormat.bigEndian != !fmt->bigEndian) { \ - pix[0] = Swap##bpp(pix[0]); \ - pix[1] = Swap##bpp(pix[1]); \ - } \ - \ - src = (CARD8 *)pCursor->richSource; \ - widthPixels = pCursor->width; \ - widthBytes = (pCursor->width*bpp)/8; \ - \ - for (y = 0; y < pCursor->height; y++) { \ - for (x = 0; x < widthPixels / 8; x++) { \ - bitmapByte = src[y * widthBytes + x]; \ - /*if (screenInfo.bitmapBitOrder == LSBFirst) { \ - bitmapByte = _reverse_byte[bitmapByte]; \ - }*/ \ - for (b = 7; b >= 0; b--) { \ - memcpy (buf, (char *)&pix[bitmapByte >> b & 1], \ - sizeof(CARD##bpp)); \ - buf += sizeof(CARD##bpp); \ - } \ - } \ - if (widthPixels % 8) { \ - bitmapByte = src[y * widthBytes + x]; \ - /*if (cl->screen.bitmapBitOrder == LSBFirst) { \ - bitmapByte = _reverse_byte[bitmapByte]; \ - }*/ \ - for (b = 7; b > 7 - widthPixels % 8; b--) { \ - memcpy (buf, (char *)&pix[bitmapByte >> b & 1], \ - sizeof(CARD##bpp)); \ - buf += sizeof(CARD##bpp); \ - } \ - } \ - } \ - \ - return (widthPixels * pCursor->height * (bpp / 8)); \ -} - -DEFINE_RICH_ENCODE(16) -DEFINE_RICH_ENCODE(32) - +/* if you have a cursor in LSB order you have to convert it */ void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap) { int i,t=(width+7)/8*height; @@ -495,7 +353,6 @@ void rfbUndrawCursor(rfbClientPtr cl) rfbCursorPtr c=s->cursor; int j,x1,x2,y1,y2,bpp=s->rfbServerFormat.bitsPerPixel/8, rowstride=s->paddedWidthInBytes; - return; if(!s->cursorIsDrawn) return; /* restore what is under the cursor */ @@ -525,7 +382,6 @@ void rfbDrawCursor(rfbClientPtr cl) 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; - return; if(s->cursorIsDrawn) rfbUndrawCursor(cl); if(s->underCursorBufferLenclientData; - //if(cl->screen->cursorIsDrawn) - //rfbUndrawCursor(cl); - //cl->screen->cursorX=x; - //cl->screen->cursorY=y; + if(cl->screen->cursorIsDrawn) + rfbUndrawCursor(cl); + cl->screen->cursorX=x; + cl->screen->cursorY=y; if(x>=0 && y>=0 && xcursor; char x[32*32],mask[32*32/8]; c=rfbScreen->cursor = rfbMakeXCursor(w,h,x,mask); + c->xhot = 2; c->yhot = 10; c->mask[0]=0xff; c->mask[1]=0x0; memset(c->mask,255,h*w/8); c->richSource = malloc(w*h*bpp); diff --git a/include/Xserver/os.h b/include/Xserver/os.h index abeac7e..1af252d 100755 --- a/include/Xserver/os.h +++ b/include/Xserver/os.h @@ -51,10 +51,10 @@ SOFTWARE. #ifndef OS_H #define OS_H -#include "misc.h" +#include "Xserver/misc.h" #define ALLOCATE_LOCAL_FALLBACK(_size) Xalloc((unsigned long)(_size)) #define DEALLOCATE_LOCAL_FALLBACK(_ptr) Xfree((pointer)(_ptr)) -#include "Xalloca.h" +#include "X11/Xalloca.h" #define NullFID ((FID) 0) diff --git a/main.c b/main.c index c67bc61..a0a3b32 100644 --- a/main.c +++ b/main.c @@ -40,6 +40,7 @@ #include #include "rfb.h" +#include "region.h" #ifdef HAVE_PTHREADS pthread_mutex_t logMutex; @@ -408,6 +409,7 @@ rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv,int width,int height, 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_* (which actually I should probably do eventually). */ + /* rfbScreen->screen.RegionCreate = miRegionCreate; rfbScreen->screen.RegionInit = miRegionInit; rfbScreen->screen.RegionCopy = miRegionCopy; @@ -426,6 +428,7 @@ rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv,int width,int height, rfbScreen->screen.RegionExtents = miRegionExtents; rfbScreen->screen.RegionAppend = miRegionAppend; rfbScreen->screen.RegionValidate = miRegionValidate; + */ rfbScreen->kbdAddEvent = defaultKbdAddEvent; rfbScreen->kbdReleaseAllKeys = doNothingWithClient; diff --git a/miregion.c b/miregion.c index 37f4927..7f4d041 100644 --- a/miregion.c +++ b/miregion.c @@ -50,10 +50,10 @@ SOFTWARE. #include #include -#include "miscstruct.h" -#include "regionstr.h" -#include "Xprotostr.h" -#include "gc.h" +#include "Xserver/miscstruct.h" +#include "Xserver/regionstr.h" +#include "X11/Xprotostr.h" +#include "Xserver/gc.h" #if defined (__GNUC__) && !defined (NO_INLINES) #define INLINE __inline @@ -61,6 +61,13 @@ SOFTWARE. #define INLINE #endif +#undef xalloc +#undef xrealloc +#undef xfree +#define xalloc malloc +#define xrealloc realloc +#define xfree free + /* * hack until callers of these functions can deal with out-of-memory */ diff --git a/pnmshow.c b/pnmshow.c index 0f29d90..d06eeb3 100644 --- a/pnmshow.c +++ b/pnmshow.c @@ -1,7 +1,6 @@ #include #include "rfb.h" -#define XK_MISCELLANY -#include "keysymdef.h" +#include "keysym.h" void HandleKey(Bool down,KeySym key,rfbClientPtr cl) { @@ -52,12 +51,20 @@ int main(int argc,char** argv) /* allocate picture and read it */ rfbScreen->frameBuffer = (char*)malloc(width*height*4); fread(rfbScreen->frameBuffer,width*3,height,in); + fclose(in); /* correct the format to 4 bytes instead of 3 */ for(i=width*height-1;i>=0;i--) { - rfbScreen->frameBuffer[i*4+3]=rfbScreen->frameBuffer[i*3+2]; - rfbScreen->frameBuffer[i*4+2]=rfbScreen->frameBuffer[i*3+1]; - rfbScreen->frameBuffer[i*4+1]=rfbScreen->frameBuffer[i*3+0]; + rfbScreen->frameBuffer[i*4+2]=rfbScreen->frameBuffer[i*3+0]; + rfbScreen->frameBuffer[i*4+1]=rfbScreen->frameBuffer[i*3+1]; + rfbScreen->frameBuffer[i*4+0]=rfbScreen->frameBuffer[i*3+2]; + } + + for(i=0;i<200;i++) { + rfbScreen->frameBuffer[i*4+i*width*4]=0; + rfbScreen->frameBuffer[i*4+i*width*4+1]=0; + rfbScreen->frameBuffer[i*4+i*width*4+2]=0; + rfbScreen->frameBuffer[i*4+i*width*4+3]=0; } /* run event loop */ diff --git a/rfb.h b/rfb.h index 77e7350..2a59d44 100644 --- a/rfb.h +++ b/rfb.h @@ -25,12 +25,69 @@ #include #include -#include "scrnintstr.h" +//#include "scrnintstr.h" /* trying to replace the above with some more minimal set of includes */ -#include "misc.h" -#include "Xmd.h" -#include "regionstr.h" +//#include "misc.h" +//#include "Xmd.h" +/* TODO: this stuff has to go into autoconf */ +typedef unsigned char CARD8; +typedef unsigned short CARD16; +typedef unsigned int CARD32; +typedef CARD32 Pixel; +typedef CARD32 KeySym; +typedef signed char Bool; +#define FALSE 0 +#define TRUE -1 +#include "keysym.h" + +/* region stuff */ +#define NullRegion ((RegionPtr)0) +#define NullBox ((BoxPtr)0) + +typedef struct _Box { + short x1, y1, x2, y2; +} BoxRec, *BoxPtr; + +typedef struct _RegData { + long size; + long numRects; +/* BoxRec rects[size]; in memory but not explicitly declared */ +} RegDataRec, *RegDataPtr; + +typedef struct _Region { + BoxRec extents; + RegDataPtr data; +} RegionRec, *RegionPtr; + +#define REGION_NIL(reg) ((reg)->data && !(reg)->data->numRects) +#define REGION_NUM_RECTS(reg) ((reg)->data ? (reg)->data->numRects : 1) +#define REGION_SIZE(reg) ((reg)->data ? (reg)->data->size : 0) +#define REGION_RECTS(reg) ((reg)->data ? (BoxPtr)((reg)->data + 1) \ + : &(reg)->extents) +#define REGION_BOXPTR(reg) ((BoxPtr)((reg)->data + 1)) +#define REGION_BOX(reg,i) (®ION_BOXPTR(reg)[i]) +#define REGION_TOP(reg) REGION_BOX(reg, (reg)->data->numRects) +#define REGION_END(reg) REGION_BOX(reg, (reg)->data->numRects - 1) +#define REGION_SZOF(n) (sizeof(RegDataRec) + ((n) * sizeof(BoxRec))) + +#define REGION_INIT(s,pReg,rect,size) miRegionInit(pReg,rect,size) +#define REGION_EMPTY(s,pReg) miRegionEmpty(pReg) +#define REGION_UNINIT(s,pReg) miRegionUninit(pReg) +#define REGION_NOTEMPTY(s,pReg) miRegionNotEmpty(pReg) +#define REGION_INTERSECT(s,newReg,reg1,reg2) miIntersect(newReg,reg1,reg2) +#define REGION_SUBTRACT(s,newReg,reg1,reg2) miSubtract(newReg,reg1,reg2) +#define REGION_UNION(s,newReg,reg1,reg2) miUnion(newReg,reg1,reg2) +#define REGION_TRANSLATE(s,pReg,x,y) miTranslateRegion(pReg,x,y) + +//#include "regionstr.h" + +#define xalloc malloc +#define xrealloc realloc +#define xfree free + +int max(int,int); + #include #include @@ -61,6 +118,7 @@ #define IF_PTHREADS(x) #endif + struct rfbClientRec; struct rfbScreenInfo; struct rfbCursor; @@ -136,6 +194,7 @@ typedef struct /* wrapped screen functions */ + /* CloseScreenProcPtr CloseScreen; CreateGCProcPtr CreateGC; PaintWindowBackgroundProcPtr PaintWindowBackground; @@ -143,10 +202,13 @@ typedef struct CopyWindowProcPtr CopyWindow; ClearToBackgroundProcPtr ClearToBackground; RestoreAreasProcPtr RestoreAreas; + */ /* additions by libvncserver */ - + + /* ScreenRec screen; + */ rfbPixelFormat rfbServerFormat; char* desktopName; char rfbThisHost[255]; @@ -287,8 +349,10 @@ typedef struct rfbClientRec { milliseconds so that several changes to the framebuffer can be combined into a single update. */ - Bool deferredUpdateScheduled; - OsTimerPtr deferredUpdateTimer; + /* no deferred timer here; server has to do it alone */ + + /* Bool deferredUpdateScheduled; + OsTimerPtr deferredUpdateTimer; */ /* translateFn points to the translation function which is used to copy and translate a rectangle from the framebuffer to an output buffer. */ diff --git a/rfbserver.c b/rfbserver.c index e97c7d8..3794f0a 100644 --- a/rfbserver.c +++ b/rfbserver.c @@ -35,6 +35,7 @@ #include #endif #include "rfb.h" +#include "region.h" rfbClientPtr pointerClient = NULL; /* Mutex for pointer events */ @@ -845,8 +846,8 @@ rfbSendFramebufferUpdate(cl, updateRegion) sendCursorShape = TRUE; } else { if (!cl->screen->cursorIsDrawn) - //rfbDrawCursor(cl); - fprintf(stderr,"rfbSpriteRestoreCursor(pScreen); not yet!\n"); + rfbDrawCursor(cl); + //fprintf(stderr,"rfbSpriteRestoreCursor(pScreen); not yet!\n"); } /* @@ -865,9 +866,9 @@ rfbSendFramebufferUpdate(cl, updateRegion) * no update is needed. */ - //REGION_INIT(pScreen,&updateRegion,NullBox,0); - //REGION_UNION(pScreen, &updateRegion, &cl->copyRegion, - // &cl->modifiedRegion); + REGION_INIT(pScreen,&updateRegion,NullBox,0); + REGION_UNION(pScreen, &updateRegion, &cl->copyRegion, + &cl->modifiedRegion); REGION_INTERSECT(pScreen, &updateRegion, &cl->requestedRegion, &updateRegion); diff --git a/sockets.c b/sockets.c index 0b2f8ac..fe20c49 100644 --- a/sockets.c +++ b/sockets.c @@ -61,6 +61,8 @@ struct timeval #include "rfb.h" +int max(int i,int j) { return(i #endif -#include "Xos.h" +#include "X11/Xos.h" #include -#include "misc.h" -#include "X.h" -#include "input.h" -#include "opaque.h" +#include "Xserver/misc.h" +#include "X11/X.h" +#include "Xserver/input.h" +#include "Xserver/opaque.h" #ifdef X_POSIX_C_SOURCE #define _POSIX_C_SOURCE X_POSIX_C_SOURCE #include