Commit 47341aa5 authored by dscho's avatar dscho

now lines are drawn for the example, first steps to make clients independent.

parent af4e0267
......@@ -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;i<maxx;++i)
for(j=0;j<maxy;++j) {
buffer[(j*maxx+i)*bpp]=i*256/maxx;
buffer[(j*maxx+i)*bpp+1]=j*256/maxy;
buffer[(j*maxx+i)*bpp+2]=(i+j)*256/(maxx*maxy);
buffer[(j*maxx+i)*bpp+3]=(i-j)*256/(maxx*maxy);
buffer[(j*maxx+i)*bpp+1]=(i+j)*256/(maxx+maxy); /* red */
buffer[(j*maxx+i)*bpp+2]=i*256/maxx; /* green */
buffer[(j*maxx+i)*bpp+3]=j*256/maxy; /* blue */
}
}
/* Here we create a structure so that every client has it's own pointer */
typedef struct ClientData {
Bool oldButton;
int oldx,oldy;
} ClientData;
void clientgone(rfbClientPtr cl)
{
free(cl->clientData);
}
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(i<j) {
if(y1>y2) { 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;i<bpp;i++)
buffer[j*rowstride+(x1+(j-y1)*(x2-x1)/(y2-y1))*bpp+i]=0xff;
} else {
if(x1>x2) { i=y2; y2=y1; y1=i; i=x2; x2=x1; x1=i; }
for(i=x1;i<=x2;i++)
for(j=0;j<bpp;j++)
buffer[(y1+(i-x1)*(y2-y1)/(x2-x1))*rowstride+i*bpp+j]=0xff;
}
}
/* Here the pointer events are handled */
void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
{
ClientData* cd=cl->clientData;
if(buttonMask && x>=0 && y>=0 && x<maxx && y<maxy) {
int i,j,x1,x2,y1,y2;
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;i<x2*bpp;i++)
for(j=y1;j<y2;j++)
cl->screen->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;i<x2*bpp;i++)
for(j=y1;j<y2;j++)
cl->screen->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);
......
......@@ -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,&region,&box,0);
rfbMarkRegionAsModified(rfbScreen,&region);
}
......@@ -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
......
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment