diff --git a/example.c b/example.c index 2fe1d3f..22d1c04 100644 --- a/example.c +++ b/example.c @@ -32,36 +32,92 @@ const int maxx=640, maxy=480, bpp=4; -void initBuffer(char* buffer) +/* This initializes a nice (?) background */ + +void initBuffer(unsigned char* buffer) { int i,j; for(i=0;iclientData); +} + +void newclient(rfbClientPtr cl) +{ + cl->clientData = (void*)calloc(sizeof(ClientData),1); + cl->clientGoneHook = clientgone; +} + +/* aux function to draw a line */ +void drawline(unsigned char* buffer,int rowstride,int bpp,int x1,int y1,int x2,int y2) +{ + int i,j; + i=x1-x2; j=y1-y2; + if(i<0) i=-i; + if(j<0) j=-j; + if(iy2) { i=y2; y2=y1; y1=i; i=x2; x2=x1; x1=i; } + if(y2==y1) { if(y2>0) y1--; else y2++; } + for(j=y1;j<=y2;j++) + for(i=0;ix2) { i=y2; y2=y1; y1=i; i=x2; x2=x1; x1=i; } + for(i=x1;i<=x2;i++) + for(j=0;jclientData; if(buttonMask && x>=0 && y>=0 && xmaxx) x2=maxx; - y1=y-buttonMask; if(y1<0) y1=0; - y2=y+buttonMask; if(y2>maxy) y2=maxy; - - for(i=x1*bpp;iscreen->frameBuffer[j*cl->screen->paddedWidthInBytes+i]=0xff; - rfbMarkRectAsModified(cl->screen,x1,y1,x2,y2); - rfbGotXCutText(cl->screen,"Hallo",5); - } -} + if(cd->oldButton==buttonMask) { /* draw a line */ + drawline(cl->screen->frameBuffer,cl->screen->paddedWidthInBytes,bpp, + x,y,cd->oldx,cd->oldy); + rfbMarkRectAsModified(cl->screen,x,y,cd->oldx,cd->oldy); + } else { /* draw a point (diameter depends on button) */ + x1=x-buttonMask; if(x1<0) x1=0; + x2=x+buttonMask; if(x2>maxx) x2=maxx; + y1=y-buttonMask; if(y1<0) y1=0; + y2=y+buttonMask; if(y2>maxy) y2=maxy; + + for(i=x1*bpp;iscreen->frameBuffer[j*cl->screen->paddedWidthInBytes+i]=0xff; + rfbMarkRectAsModified(cl->screen,x1,y1,x2-1,y2-1); + } + /* we could get a selection like that: + rfbGotXCutText(cl->screen,"Hallo",5); + */ + + cd->oldx=x; cd->oldy=y; cd->oldButton=buttonMask; + } else + cd->oldButton=0; +} + +/* Here the key events are handled */ void dokey(Bool down,KeySym key,rfbClientPtr cl) { @@ -73,21 +129,28 @@ void dokey(Bool down,KeySym key,rfbClientPtr cl) } } +/* Initialisation */ + int main(int argc,char** argv) { - rfbScreenInfoPtr rfbScreen = rfbDefaultScreenInit(argc,argv); - rfbScreen->desktopName="LibVNCServer Example"; + rfbScreenInfoPtr rfbScreen = + rfbDefaultScreenInit(argc,argv,maxx,maxy,8,3,bpp); + rfbScreen->desktopName = "LibVNCServer Example"; rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp); - rfbScreen->width=maxx; - rfbScreen->height=maxy; - rfbScreen->paddedWidthInBytes=maxx*bpp; - rfbScreen->ptrAddEvent=doptr; - rfbScreen->kbdAddEvent=dokey; + rfbScreen->rfbAlwaysShared = TRUE; + rfbScreen->ptrAddEvent = doptr; + rfbScreen->kbdAddEvent = dokey; + rfbScreen->newClientHook = newclient; initBuffer(rfbScreen->frameBuffer); + /* this is the blocking event loop, i.e. it never returns */ runEventLoop(rfbScreen,40000,FALSE); + + /* this is the non-blocking event loop; a background thread is started */ runEventLoop(rfbScreen,40000,TRUE); + + /* now we could do some cool things like rendering */ while(1); return(0); diff --git a/main.c b/main.c index ef39aa4..9736b0d 100644 --- a/main.c +++ b/main.c @@ -91,7 +91,10 @@ void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y { BoxRec box; RegionRec region; - box.x1=x1; box.y1=y1; box.x2=x2; box.y2=y2; + int i; + if(x1>x2) { i=x1; x1=x2; x2=i; } + if(y1>y2) { i=y1; y1=y2; y2=i; } + box.x1=x1; box.y1=y1; box.x2=x2+1; box.y2=y2+1; REGION_INIT(cl->screen,®ion,&box,0); rfbMarkRegionAsModified(rfbScreen,®ion); } @@ -296,10 +299,8 @@ void doNothingWithClient(rfbClientPtr cl) { } -rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv) +rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv,int width,int height,int bitsPerSample,int samplesPerPixel,int bytesPerPixel) { - int bitsPerSample,samplesPerPixel; - rfbScreenInfoPtr rfbScreen=malloc(sizeof(rfbScreenInfo)); rfbScreen->rfbPort=5900; rfbScreen->socketInitDone=FALSE; @@ -317,22 +318,22 @@ rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv) processArguments(rfbScreen,argc,argv); - rfbScreen->width = 640; - rfbScreen->height = 480; - rfbScreen->bitsPerPixel = rfbScreen->depth = 32; + rfbScreen->width = width; + rfbScreen->height = height; + rfbScreen->bitsPerPixel = rfbScreen->depth = 8*bytesPerPixel; gethostname(rfbScreen->rfbThisHost, 255); - rfbScreen->paddedWidthInBytes = 640*4; + rfbScreen->paddedWidthInBytes = width*bytesPerPixel; rfbScreen->rfbServerFormat.bitsPerPixel = rfbScreen->bitsPerPixel; rfbScreen->rfbServerFormat.depth = rfbScreen->depth; rfbScreen->rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest); rfbScreen->rfbServerFormat.trueColour = TRUE; - bitsPerSample = 8; - samplesPerPixel = 3; + /* Why? (TODO) if (samplesPerPixel != 3) { rfbLog("screen format not supported. exiting.\n"); exit(1); } + */ /* This works for 16 and 32-bit, but not for 8-bit. What should it be for 8-bit? (Shouldn't 8-bit use a colormap?) */ @@ -342,6 +343,14 @@ rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv) rfbScreen->rfbServerFormat.redShift = bitsPerSample * 2; rfbScreen->rfbServerFormat.greenShift = bitsPerSample; rfbScreen->rfbServerFormat.blueShift = 0; +fprintf(stderr,"format: %d %d %d %d %d %d\n", + rfbScreen->rfbServerFormat.redMax, + rfbScreen->rfbServerFormat.greenMax, + rfbScreen->rfbServerFormat.blueMax, + rfbScreen->rfbServerFormat.redShift, + rfbScreen->rfbServerFormat.greenShift, + rfbScreen->rfbServerFormat.blueShift); + /* We want to use the X11 REGION_* macros without having an actual X11 ScreenPtr, so we do this. Pretty ugly, but at least it lets us diff --git a/rfb.h b/rfb.h index bc3a9bc..6836c20 100644 --- a/rfb.h +++ b/rfb.h @@ -524,7 +524,7 @@ void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,RegionPtr modRegion); void doNothingWithClient(rfbClientPtr cl); /* functions to make a vnc server */ -extern rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv); +extern rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv,int width,int height,int bitsPerSample,int samplesPerPixel,int bytesPerPixel); extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo); /* call one of these two functions to service the vnc clients.