From e0168dbd9ae5e598f6564aa811cdb252330524c1 Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Sun, 18 Nov 2001 21:58:58 +0000
Subject: start x11vnc, an x0rfbserver clone

---
 Makefile    |  10 +++--
 example.c   |   2 +-
 main.c      |   5 +++
 rfb.h       |   5 ++-
 rfbserver.c |   3 +-
 x11vnc.c    | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 153 insertions(+), 7 deletions(-)
 create mode 100644 x11vnc.c

diff --git a/Makefile b/Makefile
index 17c893e..393853d 100644
--- a/Makefile
+++ b/Makefile
@@ -9,8 +9,8 @@ VNCSERVERLIB=-L. -lvncserver -L/usr/local/lib -lz -ljpeg
 # The code for 3 Bytes/Pixel is not very efficient!
 FLAG24 = -DALLOW24BPP
 
-#OPTFLAGS=-g # -Wall
-OPTFLAGS=-O2 -Wall
+OPTFLAGS=-g # -Wall
+#OPTFLAGS=-O2 -Wall
 CFLAGS=$(OPTFLAGS) $(PTHREADDEF) $(FLAG24) $(INCLUDES)
 RANLIB=ranlib
 
@@ -19,7 +19,8 @@ LIBS=$(LDFLAGS) $(VNCSERVERLIB) $(PTHREADLIB)
 # for Mac OS X
 OSX_LIBS = -framework ApplicationServices -framework Carbon
 
-# for Example
+# for x11vnc
+XLIBS =  -L/usr/X11R6/lib -lX11
 
 SOURCES=main.c rfbserver.c sraRegion.c auth.c sockets.c \
 	stats.c corre.c hextile.c rre.c translate.c cutpaste.c \
@@ -56,6 +57,9 @@ pnmshow: pnmshow.o libvncserver.a
 OSXvnc-server: mac.o libvncserver.a
 	$(CC) -o OSXvnc-server mac.o $(LIBS) $(OSX_LIBS)
 
+x11vnc: x11vnc.o libvncserver.a
+	$(CC) -o x11vnc x11vnc.o $(LIBS) $(XLIBS)
+
 storepasswd: storepasswd.o d3des.o vncauth.o
 	$(CC) -o storepasswd storepasswd.o d3des.o vncauth.o
 
diff --git a/example.c b/example.c
index 4b3810e..a3cfba9 100644
--- a/example.c
+++ b/example.c
@@ -270,7 +270,7 @@ int main(int argc,char** argv)
 #endif
 
   /* this is the non-blocking event loop; a background thread is started */
-  rfbRunEventLoop(rfbScreen,40000,TRUE);
+  rfbRunEventLoop(rfbScreen,-1,TRUE);
   /* now we could do some cool things like rendering */
   while(1) sleep(5); /* render(); */
    
diff --git a/main.c b/main.c
index f406918..9f697d7 100644
--- a/main.c
+++ b/main.c
@@ -34,6 +34,8 @@
 
 MUTEX(logMutex);
 
+char rfbEndianTest = (_BYTE_ORDER == _LITTLE_ENDIAN);
+
 /*
  * rfbLog prints a time-stamped message to the log file (stderr).
  */
@@ -580,6 +582,9 @@ rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec)
   rfbClientPtr cl,clPrev;
   struct timeval tv;
 
+  if(usec<0)
+    usec=rfbScreen->rfbDeferUpdateTime*1000;
+
   rfbCheckFds(rfbScreen,usec);
   httpCheckFds(rfbScreen);
 #ifdef CORBA
diff --git a/rfb.h b/rfb.h
index 92d4522..358d26e 100644
--- a/rfb.h
+++ b/rfb.h
@@ -37,7 +37,8 @@ typedef unsigned char CARD8;
 typedef unsigned short CARD16;
 typedef unsigned int CARD32;
 typedef CARD32 Pixel;
-typedef CARD32 KeySym;
+/* typedef CARD32 KeySym; */
+typedef unsigned long KeySym;
 #define SIGNED signed
 /* for some strange reason, "typedef signed char Bool;" yields a four byte
    signed int on IRIX, but only for rfbserver.o!!! */
@@ -518,7 +519,7 @@ typedef struct rfbClientRec {
                    ((l) << 24))
 
 
-static const int rfbEndianTest = (_BYTE_ORDER == _LITTLE_ENDIAN);
+extern char rfbEndianTest;
 
 #define Swap16IfLE(s) (rfbEndianTest ? Swap16(s) : (s))
 #define Swap24IfLE(l) (rfbEndianTest ? Swap24(l) : (l))
diff --git a/rfbserver.c b/rfbserver.c
index b75d1c7..34ac38e 100644
--- a/rfbserver.c
+++ b/rfbserver.c
@@ -328,7 +328,8 @@ rfbClientConnectionGone(cl)
     }
 #endif
 
-	 FD_CLR(cl->sock,&(cl->screen->allFds));
+    if(cl->sock>=0)
+       FD_CLR(cl->sock,&(cl->screen->allFds));
 
     cl->clientGoneHook(cl);
 
diff --git a/x11vnc.c b/x11vnc.c
new file mode 100644
index 0000000..205d505
--- /dev/null
+++ b/x11vnc.c
@@ -0,0 +1,135 @@
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#define KEYSYM_H
+#include "rfb.h"
+
+int c=0,blockLength = 32;
+
+void getImage(Display *dpy,int xscreen,XImage **i)
+{
+  *i = XGetImage( dpy,
+		  RootWindow(dpy,xscreen),
+		  0,0,
+		  DisplayWidth(dpy,xscreen),
+		  DisplayHeight(dpy,xscreen),
+		  AllPlanes,
+		  ZPixmap );
+}
+
+void checkForImageUpdates(rfbScreenInfoPtr s,char *b)
+{
+   Bool changed;
+   int i,j,k,l,x1,y1;
+   for(j=0;j<s->height;j+=blockLength)
+     for(i=0;i<s->width;i+=blockLength) {
+	y1=j+blockLength; if(y1>s->height) y1=s->height;
+	x1=i+blockLength; if(x1>s->width) x1=s->width;
+	y1*=s->paddedWidthInBytes;
+	x1*=s->bitsPerPixel/8;
+	changed=FALSE;
+	for(l=j*s->paddedWidthInBytes;!changed&&l<y1;l+=s->paddedWidthInBytes)
+	  for(k=i*s->bitsPerPixel/8;k<x1;k++)
+	    if(s->frameBuffer[l+k]!=b[l+k]) {
+//	       fprintf(stderr,"changed: %d, %d\n",k,l);
+	       changed=TRUE;
+	       goto changed_p;
+	    }
+	if(changed) {
+	   changed_p:
+	  for(;l<0*y1;l++)
+	     memcpy(/*b+l,*/s->frameBuffer+l,b+l,x1-l);
+	   rfbMarkRectAsModified(s,i,j,i+blockLength,j+blockLength);
+	}
+     }
+}
+
+int main(int argc,char** argv)
+{
+  XImage *framebufferImage;
+  char *backupImage;
+  Display *dpy;
+  int xscreen;
+  rfbScreenInfoPtr screen;
+
+  dpy = XOpenDisplay("");
+  xscreen = DefaultScreen(dpy);
+
+  getImage(dpy,xscreen,&framebufferImage);
+
+  screen = rfbGetScreen(&argc,argv,framebufferImage->width,
+			framebufferImage->height,
+			framebufferImage->bits_per_pixel,
+			8,
+			framebufferImage->bits_per_pixel/8);
+   
+  screen->paddedWidthInBytes = framebufferImage->bytes_per_line;
+
+  screen->rfbServerFormat.bitsPerPixel = framebufferImage->bits_per_pixel;
+  screen->rfbServerFormat.depth = framebufferImage->depth;
+  rfbEndianTest = framebufferImage->bitmap_bit_order != MSBFirst;
+  screen->rfbServerFormat.trueColour = TRUE;
+
+  if ( screen->rfbServerFormat.bitsPerPixel == 8 ) {
+    screen->rfbServerFormat.redShift = 0;
+    screen->rfbServerFormat.greenShift = 2;
+    screen->rfbServerFormat.blueShift = 5;
+    screen->rfbServerFormat.redMax   = 3;
+    screen->rfbServerFormat.greenMax = 7;
+    screen->rfbServerFormat.blueMax  = 3;
+  } else {
+    screen->rfbServerFormat.redShift = 0;
+    if ( framebufferImage->red_mask )
+      while ( ! ( framebufferImage->red_mask & (1 << screen->rfbServerFormat.redShift) ) )
+        screen->rfbServerFormat.redShift++;
+    screen->rfbServerFormat.greenShift = 0;
+    if ( framebufferImage->green_mask )
+      while ( ! ( framebufferImage->green_mask & (1 << screen->rfbServerFormat.greenShift) ) )
+        screen->rfbServerFormat.greenShift++;
+    screen->rfbServerFormat.blueShift = 0;
+    if ( framebufferImage->blue_mask )
+      while ( ! ( framebufferImage->blue_mask & (1 << screen->rfbServerFormat.blueShift) ) )
+      screen->rfbServerFormat.blueShift++;
+    screen->rfbServerFormat.redMax   = framebufferImage->red_mask   >> screen->rfbServerFormat.redShift;
+    screen->rfbServerFormat.greenMax = framebufferImage->green_mask >> screen->rfbServerFormat.greenShift;
+    screen->rfbServerFormat.blueMax  = framebufferImage->blue_mask  >> screen->rfbServerFormat.blueShift;
+  }
+
+  backupImage = malloc(screen->height*screen->paddedWidthInBytes);
+  //memcpy(backupImage,framebufferImage->data,screen->height*screen->paddedWidthInBytes);
+  screen->frameBuffer = backupImage;
+  screen->rfbDeferUpdateTime = 500;
+  screen->cursor = 0;
+
+  rfbInitServer(screen);
+   
+  while(1) {
+    rfbProcessEvents(screen,-1);
+    if(1 || /*c++>7 &&*/ (!screen->rfbClientHead || !FB_UPDATE_PENDING(screen->rfbClientHead))) {
+       c=0;
+    framebufferImage->f.destroy_image(framebufferImage);
+    getImage(dpy,xscreen,&framebufferImage);
+    //checkForImageUpdates(screen,framebufferImage->data);
+    }
+     fprintf(stderr,"%x\n%x\n---\n",screen->frameBuffer,framebufferImage->data);
+   memcpy(screen->frameBuffer,framebufferImage->data,screen->height/10*screen->paddedWidthInBytes);
+   rfbMarkRectAsModified(screen,0,0,screen->width,screen->height);
+#if 0
+       {
+	  int i,j,r,g,b;
+	  FILE* f=fopen("test.pnm","wb");
+	  fprintf(f,"P6\n%d %d\n255\n",screen->width,screen->height);
+	  for(j=0;j<screen->height;j++)
+	    for(i=0;i<screen->width;i++) {
+	       //r=screen->frameBuffer[j*screen->paddedWidthInBytes+i*2];
+	       r=framebufferImage->data[j*screen->paddedWidthInBytes+i*2];
+	       fputc(((r>>screen->rfbServerFormat.redShift)&screen->rfbServerFormat.redMax)*255/screen->rfbServerFormat.redMax,f);
+	       fputc(((r>>screen->rfbServerFormat.greenShift)&screen->rfbServerFormat.greenMax)*255/screen->rfbServerFormat.greenMax,f);
+	       fputc(((r>>screen->rfbServerFormat.blueShift)&screen->rfbServerFormat.blueMax)*255/screen->rfbServerFormat.blueMax,f);
+	    }
+	  fclose(f);
+       }
+#endif
+  }
+
+  return(0);
+}
-- 
cgit v1.2.3

