diff --git a/Makefile b/Makefile index 9227e99..93287be 100644 --- a/Makefile +++ b/Makefile @@ -24,11 +24,11 @@ OSX_LIBS = -framework ApplicationServices -framework Carbon SOURCES=main.c rfbserver.c sraRegion.c auth.c sockets.c \ stats.c corre.c hextile.c rre.c translate.c cutpaste.c \ zlib.c tight.c httpd.c cursor.c font.c \ - draw.c selbox.c d3des.c vncauth.c + draw.c selbox.c d3des.c vncauth.c cargs.c OBJS=main.o rfbserver.o sraRegion.o auth.o sockets.o \ stats.o corre.o hextile.o rre.o translate.o cutpaste.o \ zlib.o tight.o httpd.o cursor.o font.o \ - draw.o selbox.o d3des.o vncauth.o + draw.o selbox.o d3des.o vncauth.o cargs.o INSTALLHEADER=rfb.h rfbproto.h sraRegion.h keysym.h all: example pnmshow storepasswd @@ -80,6 +80,10 @@ fontsel: fontsel.o libvncserver.a vncev: vncev.o libvncserver.a $(CC) -o vncev vncev.o -L. -lvncserver -lz -ljpeg +# Example from Justin +zippy: zippy.o libvncserver.a + $(CC) -o zippy zippy.o -L. -lvncserver -lz -ljpeg + clean: rm -f $(OBJS) *~ core "#"* *.bak *.orig storepasswd.o \ mac.o example.o pnmshow.o pnmshow24.o sratest.o \ diff --git a/d3des.h b/d3des.h index ea3da44..b2f9724 100644 --- a/d3des.h +++ b/d3des.h @@ -1,3 +1,6 @@ +#ifndef D3DES_H +#define D3DES_H + /* * This is D3DES (V5.09) by Richard Outerbridge with the double and * triple-length support removed for use in VNC. @@ -49,3 +52,5 @@ extern void des(unsigned char *, unsigned char *); /* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery ********************************************************************/ + +#endif diff --git a/example.c b/example.c index 9ed6846..4b3810e 100644 --- a/example.c +++ b/example.c @@ -239,7 +239,7 @@ void MakeRichCursor(rfbScreenInfoPtr rfbScreen) int main(int argc,char** argv) { rfbScreenInfoPtr rfbScreen = - rfbGetScreen(argc,argv,maxx,maxy,8,3,bpp); + rfbGetScreen(&argc,argv,maxx,maxy,8,3,bpp); rfbScreen->desktopName = "LibVNCServer Example"; rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp); rfbScreen->rfbAlwaysShared = TRUE; diff --git a/fontsel.c b/fontsel.c index 81d4699..100db81 100644 --- a/fontsel.c +++ b/fontsel.c @@ -38,7 +38,7 @@ void showFont(int index) int main(int argc,char** argv) { rfbFontDataPtr font; - rfbScreenInfoPtr s=rfbGetScreen(argc,argv,640,480,8,3,3); + rfbScreenInfoPtr s=rfbGetScreen(&argc,argv,640,480,8,3,3); int i,j; s->frameBuffer=(char*)malloc(640*480*3); diff --git a/keysym.h b/keysym.h index f500e03..dc165b3 100755 --- a/keysym.h +++ b/keysym.h @@ -1,3 +1,6 @@ +#ifndef KEYSYM_H +#define KEYSYM_H + /* $XConsortium: keysym.h,v 1.15 94/04/17 20:10:55 rws Exp $ */ /*********************************************************** @@ -1632,3 +1635,5 @@ SOFTWARE. /* Euro currency symbol */ #define XK_EuroSign 0x20ac + +#endif diff --git a/mac.c b/mac.c index 16487b1..0f1332b 100644 --- a/mac.c +++ b/mac.c @@ -266,7 +266,7 @@ PtrAddEvent(buttonMask, x, y, cl) void ScreenInit(int argc, char**argv) { - rfbScreen = rfbGetScreen(argc,argv, + rfbScreen = rfbGetScreen(&argc,argv, CGDisplayPixelsWide(kCGDirectMainDisplay), CGDisplayPixelsHigh(kCGDirectMainDisplay), CGDisplayBitsPerSample(kCGDirectMainDisplay), diff --git a/main.c b/main.c index e607f14..6e2ad2b 100644 --- a/main.c +++ b/main.c @@ -209,8 +209,6 @@ void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y sraRgnDestroy(region); } -int rfbDeferUpdateTime = 40; /* ms */ - #ifdef HAVE_PTHREADS static void * clientOutput(void *data) @@ -243,7 +241,7 @@ clientOutput(void *data) /* OK, now, to save bandwidth, wait a little while for more updates to come along. */ - usleep(rfbDeferUpdateTime * 1000); + usleep(cl->screen->rfbDeferUpdateTime * 1000); /* Now, get the region we're going to update, and remove it from cl->modifiedRegion _before_ we send the update. @@ -312,58 +310,6 @@ listenerRun(void *data) } #endif -static void -usage(void) -{ - fprintf(stderr, "-rfbport port TCP port for RFB protocol\n"); - fprintf(stderr, "-rfbwait time max time in ms to wait for RFB client\n"); - fprintf(stderr, "-rfbauth passwd-file use authentication on RFB protocol\n" - " (use 'storepasswd' to create a password file)\n"); - fprintf(stderr, "-deferupdate time time in ms to defer updates " - "(default 40)\n"); - fprintf(stderr, "-desktop name VNC desktop name (default \"LibVNCServer\")\n"); - fprintf(stderr, "-alwaysshared always treat new clients as shared\n"); - fprintf(stderr, "-nevershared never treat new clients as shared\n"); - fprintf(stderr, "-dontdisconnect don't disconnect existing clients when a " - "new non-shared\n" - " connection comes in (refuse new connection " - "instead)\n"); - exit(1); -} - -static void -processArguments(rfbScreenInfoPtr rfbScreen,int argc, char *argv[]) -{ - int i; - - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-rfbport") == 0) { /* -rfbport port */ - if (i + 1 >= argc) usage(); - rfbScreen->rfbPort = atoi(argv[++i]); - } else if (strcmp(argv[i], "-rfbwait") == 0) { /* -rfbwait ms */ - if (i + 1 >= argc) usage(); - rfbScreen->rfbMaxClientWait = atoi(argv[++i]); - } else if (strcmp(argv[i], "-rfbauth") == 0) { /* -rfbauth passwd-file */ - if (i + 1 >= argc) usage(); - rfbScreen->rfbAuthPasswdData = argv[++i]; - } else if (strcmp(argv[i], "-deferupdate") == 0) { /* -desktop desktop-name */ - if (i + 1 >= argc) usage(); - rfbScreen->rfbDeferUpdateTime = atoi(argv[++i]); - } else if (strcmp(argv[i], "-desktop") == 0) { /* -desktop desktop-name */ - if (i + 1 >= argc) usage(); - rfbScreen->desktopName = argv[++i]; - } else if (strcmp(argv[i], "-alwaysshared") == 0) { - rfbScreen->rfbAlwaysShared = TRUE; - } else if (strcmp(argv[i], "-nevershared") == 0) { - rfbScreen->rfbNeverShared = TRUE; - } else if (strcmp(argv[i], "-dontdisconnect") == 0) { - rfbScreen->rfbDontDisconnect = TRUE; - } else { - /* usage(); we no longer exit for unknown arguments */ - } - } -} - void defaultKbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl) { @@ -451,11 +397,30 @@ Bool defaultPasswordCheck(rfbClientPtr cl,char* response,int len) return(TRUE); } +/* for this method, rfbAuthPasswdData is really a pointer to an array + of char*'s, where the last pointer is 0. */ +Bool checkPasswordByList(rfbClientPtr cl,char* response,int len) +{ + int i; + char **passwds; + + for(passwds=(char**)cl->screen->rfbAuthPasswdData;*passwds;passwds++) { + vncEncryptBytes(cl->authChallenge, *passwds); + + if (memcmp(cl->authChallenge, response, len) == 0) + return(TRUE); + } + + rfbLog("rfbAuthProcessClientMessage: authentication failed from %s\n", + cl->host); + return(FALSE); +} + void doNothingWithClient(rfbClientPtr cl) { } -rfbScreenInfoPtr rfbGetScreen(int argc,char** argv, +rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv, int width,int height,int bitsPerSample,int samplesPerPixel, int bytesPerPixel) { @@ -495,11 +460,12 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv, rfbScreen->rfbDontDisconnect = FALSE; rfbScreen->rfbAuthPasswdData = 0; - processArguments(rfbScreen,argc,argv); - rfbScreen->width = width; rfbScreen->height = height; rfbScreen->bitsPerPixel = rfbScreen->depth = 8*bytesPerPixel; + + rfbProcessArguments(rfbScreen,argc,argv); + #ifdef WIN32 { DWORD dummy=255; @@ -555,6 +521,8 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv, IF_PTHREADS(rfbScreen->backgroundLoop = FALSE); + rfbScreen->rfbDeferUpdateTime=5; + /* proc's and hook's */ rfbScreen->kbdAddEvent = defaultKbdAddEvent; @@ -575,20 +543,14 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv, void rfbScreenCleanup(rfbScreenInfoPtr rfbScreen) { - /* TODO */ - if(rfbScreen->frameBuffer) - free(rfbScreen->frameBuffer); + /* TODO: hang up on all clients and free all reserved memory */ if(rfbScreen->colourMap.data.bytes) free(rfbScreen->colourMap.data.bytes); TINI_MUTEX(rfbScreen->cursorMutex); free(rfbScreen); } -#ifdef HAVE_PTHREADS -void rfbInitServerWithPthreads(rfbScreenInfoPtr rfbScreen) -#else void rfbInitServer(rfbScreenInfoPtr rfbScreen) -#endif { #ifdef WIN32 WSADATA trash; @@ -629,7 +591,9 @@ rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec) cl=rfbClientIteratorNext(i); while(cl) { if(cl->sock>=0 && FB_UPDATE_PENDING(cl)) { - if(cl->startDeferring.tv_usec == 0) { + if(cl->screen->rfbDeferUpdateTime == 0) { + rfbSendFramebufferUpdate(cl,cl->modifiedRegion); + } else if(cl->startDeferring.tv_usec == 0) { gettimeofday(&cl->startDeferring,NULL); if(cl->startDeferring.tv_usec == 0) cl->startDeferring.tv_usec++; @@ -668,6 +632,9 @@ void rfbRunEventLoop(rfbScreenInfoPtr rfbScreen, long usec, Bool runInBackground #endif } + if(usec<0) + usec=rfbScreen->rfbDeferUpdateTime*1000; + while(1) rfbProcessEvents(rfbScreen,usec); } diff --git a/pnmshow.c b/pnmshow.c index 8f4ceed..05e45b9 100644 --- a/pnmshow.c +++ b/pnmshow.c @@ -45,7 +45,7 @@ int main(int argc,char** argv) paddedWidth+=4-(width&3); /* initialize data for vnc server */ - rfbScreen = rfbGetScreen(argc,argv,paddedWidth,height,8,3,4); + rfbScreen = rfbGetScreen(&argc,argv,paddedWidth,height,8,3,4); if(argc>1) rfbScreen->desktopName = argv[1]; else diff --git a/pnmshow24.c b/pnmshow24.c index bb6821e..3978f00 100644 --- a/pnmshow24.c +++ b/pnmshow24.c @@ -52,7 +52,7 @@ int main(int argc,char** argv) paddedWidth+=4-(width&3); /* initialize data for vnc server */ - rfbScreen = rfbGetScreen(argc,argv,paddedWidth,height,8,3,3); + rfbScreen = rfbGetScreen(&argc,argv,paddedWidth,height,8,3,3); if(argc>1) rfbScreen->desktopName = argv[1]; else diff --git a/rfb.h b/rfb.h index aee123c..67857fb 100644 --- a/rfb.h +++ b/rfb.h @@ -1,3 +1,6 @@ +#ifndef RFB_H +#define RFB_H + /* * rfb.h - header file for RFB DDX implementation. */ @@ -285,7 +288,9 @@ typedef struct Bool dontConvertRichCursorToXCursor; struct rfbCursor* cursor; - /* the following members have to be supplied by the serving process */ + /* the frameBufferhas to be supplied by the serving process. + * The buffer will not be freed by + */ char* frameBuffer; KbdAddEventProcPtr kbdAddEvent; KbdReleaseAllKeysProcPtr kbdReleaseAllKeys; @@ -720,6 +725,12 @@ extern int rfbSelectBox(rfbScreenInfoPtr rfbScreen, Pixel foreColour, Pixel backColour, int border,SelectionChangedHookPtr selChangedHook); +/* cargs.c */ + +extern void rfbUsage(); +extern void rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[]); +extern void rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[]); + /* main.c */ extern void rfbLog(char *format, ...); @@ -736,7 +747,7 @@ void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion); void doNothingWithClient(rfbClientPtr cl); /* functions to make a vnc server */ -extern rfbScreenInfoPtr rfbGetScreen(int argc,char** argv, +extern rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv, int width,int height,int bitsPerSample,int samplesPerPixel, int bytesPerPixel); extern void rfbInitServer(rfbScreenInfoPtr rfbScreen); @@ -749,3 +760,5 @@ extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo); extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, Bool runInBackground); extern void rfbProcessEvents(rfbScreenInfoPtr screenInfo,long usec); + +#endif diff --git a/rfbproto.h b/rfbproto.h index 5ef1d90..2103c81 100644 --- a/rfbproto.h +++ b/rfbproto.h @@ -1,3 +1,6 @@ +#ifndef RFBPROTO_H +#define RFBPROTO_H + /* * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. @@ -783,3 +786,5 @@ typedef union { rfbPointerEventMsg pe; rfbClientCutTextMsg cct; } rfbClientToServerMsg; + +#endif diff --git a/sraRegion.h b/sraRegion.h index 7606555..3d7c50c 100755 --- a/sraRegion.h +++ b/sraRegion.h @@ -1,3 +1,6 @@ +#ifndef SRAREGION_H +#define SRAREGION_H + /* -=- SRA - Simple Region Algorithm * A simple rectangular region implementation. * Copyright (c) 2001 James "Wez" Weatherall, Johannes E. Schindelin @@ -53,3 +56,5 @@ void sraRgnPrint(const sraRegion *s); extern Bool sraClipRect(int *x, int *y, int *w, int *h, int cx, int cy, int cw, int ch); + +#endif diff --git a/vncev.c b/vncev.c index ca3b379..ba00f9c 100644 --- a/vncev.c +++ b/vncev.c @@ -99,7 +99,7 @@ void newclient(rfbClientPtr cl) int main(int argc,char** argv) { - rfbScreenInfoPtr s=rfbGetScreen(argc,argv,640,480,8,1,1); + rfbScreenInfoPtr s=rfbGetScreen(&argc,argv,640,480,8,1,1); s->colourMap.is16=FALSE; s->colourMap.count=2; s->colourMap.data.bytes="\xd0\xd0\xd0\x30\x01\xe0"; diff --git a/zippy.c b/zippy.c new file mode 100644 index 0000000..2f35059 --- /dev/null +++ b/zippy.c @@ -0,0 +1,182 @@ +#include +#include +#include +#include +#include "radon.h" + +int maxx=400, maxy=400, bpp=4; +/* odd maxx doesn't work (vncviewer bug) */ + +/* Here we create a structure so that every client has it's own pointer */ + +/* turns the framebuffer black */ +void blank_framebuffer(char* frame_buffer, int x1, int y1, int x2, int y2); +/* displays a red bar, a green bar, and a blue bar */ +void draw_primary_colors (char* frame_buffer, int x1, int y1, int x2, int y2); +void linecount (char* frame_buffer); +/* handles mouse events */ +void on_mouse_event (int buttonMask,int x,int y,rfbClientPtr cl); +/* handles keyboard events */ +void on_key_press (Bool down,KeySym key,rfbClientPtr cl); + +int main (int argc, char **argv) +{ + int i; + rfbScreenInfoPtr server; + + rfbProcessSizeArguments(&maxx,&maxy,&bpp,&argc,argv); + + server = rfbGetScreen (&argc, argv, maxx, maxy, 8, 3, bpp); + server->desktopName = "Zippy das wundersquirrel\'s VNC server"; + server->frameBuffer = (char*)malloc(maxx*maxy*bpp); + server->rfbAlwaysShared = TRUE; + server->kbdAddEvent = on_key_press; + server->ptrAddEvent = on_mouse_event; + + rfbInitServer (server); + + blank_framebuffer(server->frameBuffer, 0, 0, maxx, maxy); + rfbRunEventLoop (server, -1, FALSE); + free(server->frameBuffer); + rfbScreenCleanup (server); + return 0; +} + +void blank_framebuffer(char* frame_buffer, int x1, int y1, int x2, int y2) +{ + int i; + for (i=0; i < maxx * maxy * bpp; i++) frame_buffer[i]=(char) 0; +} + +void draw_primary_colors (char* frame_buffer, int x1, int y1, int x2, int y2) +{ + int i, j, current_pixel; + for (i=y1; i < y2; i++){ + for (j=x1; j < x2; j++) { + current_pixel = (i*x2 + j) * bpp; + if (i < y2 ) { + frame_buffer[current_pixel+0] = (char) 128; + frame_buffer[current_pixel+1] = (char) 0; + frame_buffer[current_pixel+2] = (char) 0; + } + if (i < y2/3*2) { + frame_buffer[current_pixel+0] = (char) 0; + frame_buffer[current_pixel+1] = (char) 128; + frame_buffer[current_pixel+2] = (char) 0; + } + if (i < y2/3) { + frame_buffer[current_pixel+0] = (char) 0; + frame_buffer[current_pixel+1] = (char) 0; + frame_buffer[current_pixel+2] = (char) 128; + } + } + } + } + +/* Dscho's versions (slower, but works for bpp != 3 or 4) */ +void draw_primary_colours_generic(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2) +{ + rfbPixelFormat f=s->rfbServerFormat; + int i,j; + for(j=y1;jrfbServerFormat; + int i,j,y3=(y1*2+y2)/3,y4=(y1+y2*2)/3; + /* draw first pixel */ + rfbDrawPixel(s,x1,y1,f.redMax<frameBuffer+(x)*bpp+(y)*s->paddedWidthInBytes + memcpy(ADDR(i,j+y1),ADDR(x1,y1),bpp); + memcpy(ADDR(i,j+y3),ADDR(x1,y3),bpp); + memcpy(ADDR(i,j+y4),ADDR(x1,y4),bpp); + } +} + +void draw_primary_colours_generic_ultrafast(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2) +{ + rfbPixelFormat f=s->rfbServerFormat; + int i,j,y3=(y1*2+y2)/3,y4=(y1+y2*2)/3; + /* fill rectangles */ + rfbFillRect(s,x1,y1,x2,y3,f.redMax<maxy-20; i-=4) + for (j=0; j<4; j++) for (k=0; k < maxx; k++) { + current_pixel = (i*j*maxx + k) * bpp; + if (i%2 == 0) { + frame_buffer[current_pixel+0] = (char) 0; + frame_buffer[current_pixel+1] = (char) 0; + frame_buffer[current_pixel+2] = (char) 128; + } + + if (i%2 == 1) { + frame_buffer[current_pixel+0] = (char) 128; + frame_buffer[current_pixel+1] = (char) 0; + frame_buffer[current_pixel+2] = (char) 0; + } + } + +} + + +void on_key_press (Bool down,KeySym key,rfbClientPtr cl) +{ + if (down) //or else the action occurs on both the press and depress + switch (key) { + + case XK_b: + case XK_B: + rfbUndrawCursor(cl->screen); + blank_framebuffer(cl->screen->frameBuffer, 0, 0, maxx, maxy); + rfbDrawString(cl->screen,&radonFont,20,maxy-20,"Hello, World!",0xffffff); + rfbMarkRectAsModified(cl->screen,0, 0,maxx,maxy); + fprintf (stderr, "Framebuffer blanked\n"); + break; + case XK_p: + case XK_P: + rfbUndrawCursor(cl->screen); + /* draw_primary_colors (cl->screen->frameBuffer, 0, 0, maxx, maxy); */ + draw_primary_colours_generic_ultrafast (cl->screen, 0, 0, maxx, maxy); + rfbMarkRectAsModified(cl->screen,0, 0,maxx,maxy); + fprintf (stderr, "Primary colors displayed\n"); + break; + case XK_Q: + case XK_q: + fprintf (stderr, "Exiting now\n"); + exit(0); + case XK_C: + case XK_c: + rfbUndrawCursor(cl->screen); + rfbDrawString(cl->screen,&radonFont,20,100,"Hello, World!",0xffffff); + rfbMarkRectAsModified(cl->screen,0, 0,maxx,maxy); + break; + default: + fprintf (stderr, "The %c key was pressed\n", (char) key); + } +} + + +void on_mouse_event (int buttonMask,int x,int y,rfbClientPtr cl) +{ + printf("buttonMask: %i\n" + "x: %i\n" "y: %i\n", buttonMask, x, y); +}