From 5c438e3fb2d98f6aa36b58610ed9d871a41cf6f1 Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Mon, 24 Sep 2001 22:02:28 +0000
Subject: 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->underCursorBufferLen<bufSize) {
diff --git a/example.c b/example.c
index 1f53bd9..3c4f0a4 100644
--- a/example.c
+++ b/example.c
@@ -28,9 +28,10 @@
 #endif
 #define XK_MISCELLANY
 #include "rfb.h"
-#include "keysymdef.h"
+#include "keysym.h"
 
 const int maxx=640, maxy=480, bpp=4;
+/* TODO: odd maxx doesn't work */
 
 /* This initializes a nice (?) background */
 
@@ -94,10 +95,10 @@ 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)
 {
    ClientData* cd=cl->clientData;
-   //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 && x<maxx && y<maxy) {
       if(buttonMask) {
 	 int i,j,x1,x2,y1,y2;
@@ -252,6 +253,7 @@ int main(int argc,char** argv)
      rfbCursorPtr c = rfbScreen->cursor;
      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 <time.h>
 
 #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 <stdio.h>
 #include <stdlib.h>
-#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 <stdio.h>
 #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 <stdlib.h>
 #include <string.h>
-#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) (&REGION_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 <zlib.h>
 
 #include <rfbproto.h>
@@ -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 <pthread.h>
 #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<j?j:i); }
+
 int rfbMaxClientWait = 20000;   /* time (ms) after which we decide client has
                                    gone away - needed to stop us hanging */
 
diff --git a/xalloc.c b/xalloc.c
index acccb67..23ff234 100644
--- a/xalloc.c
+++ b/xalloc.c
@@ -13,12 +13,12 @@
 #ifdef WIN32
 #include <X11/Xwinsock.h>
 #endif
-#include "Xos.h"
+#include "X11/Xos.h"
 #include <stdio.h>
-#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 <signal.h>
-- 
cgit v1.2.3

