From e0168dbd9ae5e598f6564aa811cdb252330524c1 Mon Sep 17 00:00:00 2001 From: dscho Date: Sun, 18 Nov 2001 21:58:58 +0000 Subject: [PATCH] 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 +#include +#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;jheight;j+=blockLength) + for(i=0;iwidth;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&&lpaddedWidthInBytes) + for(k=i*s->bitsPerPixel/8;kframeBuffer[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;jheight;j++) + for(i=0;iwidth;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); +}