Commit 47341aa5 authored by dscho's avatar dscho

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

parent af4e0267
...@@ -32,22 +32,71 @@ ...@@ -32,22 +32,71 @@
const int maxx=640, maxy=480, bpp=4; 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; int i,j;
for(i=0;i<maxx;++i) for(i=0;i<maxx;++i)
for(j=0;j<maxy;++j) { for(j=0;j<maxy;++j) {
buffer[(j*maxx+i)*bpp]=i*256/maxx; buffer[(j*maxx+i)*bpp+1]=(i+j)*256/(maxx+maxy); /* red */
buffer[(j*maxx+i)*bpp+1]=j*256/maxy; buffer[(j*maxx+i)*bpp+2]=i*256/maxx; /* green */
buffer[(j*maxx+i)*bpp+2]=(i+j)*256/(maxx*maxy); buffer[(j*maxx+i)*bpp+3]=j*256/maxy; /* blue */
buffer[(j*maxx+i)*bpp+3]=(i-j)*256/(maxx*maxy);
} }
} }
/* 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) void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
{ {
ClientData* cd=cl->clientData;
if(buttonMask && x>=0 && y>=0 && x<maxx && y<maxy) { if(buttonMask && x>=0 && y>=0 && x<maxx && y<maxy) {
int i,j,x1,x2,y1,y2; int i,j,x1,x2,y1,y2;
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; x1=x-buttonMask; if(x1<0) x1=0;
x2=x+buttonMask; if(x2>maxx) x2=maxx; x2=x+buttonMask; if(x2>maxx) x2=maxx;
y1=y-buttonMask; if(y1<0) y1=0; y1=y-buttonMask; if(y1<0) y1=0;
...@@ -56,12 +105,19 @@ void doptr(int buttonMask,int x,int y,rfbClientPtr cl) ...@@ -56,12 +105,19 @@ void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
for(i=x1*bpp;i<x2*bpp;i++) for(i=x1*bpp;i<x2*bpp;i++)
for(j=y1;j<y2;j++) for(j=y1;j<y2;j++)
cl->screen->frameBuffer[j*cl->screen->paddedWidthInBytes+i]=0xff; cl->screen->frameBuffer[j*cl->screen->paddedWidthInBytes+i]=0xff;
rfbMarkRectAsModified(cl->screen,x1,y1,x2,y2); rfbMarkRectAsModified(cl->screen,x1,y1,x2-1,y2-1);
rfbGotXCutText(cl->screen,"Hallo",5);
} }
}
/* 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) void dokey(Bool down,KeySym key,rfbClientPtr cl)
{ {
...@@ -73,21 +129,28 @@ 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) int main(int argc,char** argv)
{ {
rfbScreenInfoPtr rfbScreen = rfbDefaultScreenInit(argc,argv); rfbScreenInfoPtr rfbScreen =
rfbScreen->desktopName="LibVNCServer Example"; rfbDefaultScreenInit(argc,argv,maxx,maxy,8,3,bpp);
rfbScreen->desktopName = "LibVNCServer Example";
rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp); rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp);
rfbScreen->width=maxx; rfbScreen->rfbAlwaysShared = TRUE;
rfbScreen->height=maxy; rfbScreen->ptrAddEvent = doptr;
rfbScreen->paddedWidthInBytes=maxx*bpp; rfbScreen->kbdAddEvent = dokey;
rfbScreen->ptrAddEvent=doptr; rfbScreen->newClientHook = newclient;
rfbScreen->kbdAddEvent=dokey;
initBuffer(rfbScreen->frameBuffer); initBuffer(rfbScreen->frameBuffer);
/* this is the blocking event loop, i.e. it never returns */
runEventLoop(rfbScreen,40000,FALSE); runEventLoop(rfbScreen,40000,FALSE);
/* this is the non-blocking event loop; a background thread is started */
runEventLoop(rfbScreen,40000,TRUE); runEventLoop(rfbScreen,40000,TRUE);
/* now we could do some cool things like rendering */
while(1); while(1);
return(0); return(0);
......
...@@ -91,7 +91,10 @@ void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y ...@@ -91,7 +91,10 @@ void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y
{ {
BoxRec box; BoxRec box;
RegionRec region; 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); REGION_INIT(cl->screen,&region,&box,0);
rfbMarkRegionAsModified(rfbScreen,&region); rfbMarkRegionAsModified(rfbScreen,&region);
} }
...@@ -296,10 +299,8 @@ void doNothingWithClient(rfbClientPtr cl) ...@@ -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)); rfbScreenInfoPtr rfbScreen=malloc(sizeof(rfbScreenInfo));
rfbScreen->rfbPort=5900; rfbScreen->rfbPort=5900;
rfbScreen->socketInitDone=FALSE; rfbScreen->socketInitDone=FALSE;
...@@ -317,22 +318,22 @@ rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv) ...@@ -317,22 +318,22 @@ rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv)
processArguments(rfbScreen,argc,argv); processArguments(rfbScreen,argc,argv);
rfbScreen->width = 640; rfbScreen->width = width;
rfbScreen->height = 480; rfbScreen->height = height;
rfbScreen->bitsPerPixel = rfbScreen->depth = 32; rfbScreen->bitsPerPixel = rfbScreen->depth = 8*bytesPerPixel;
gethostname(rfbScreen->rfbThisHost, 255); gethostname(rfbScreen->rfbThisHost, 255);
rfbScreen->paddedWidthInBytes = 640*4; rfbScreen->paddedWidthInBytes = width*bytesPerPixel;
rfbScreen->rfbServerFormat.bitsPerPixel = rfbScreen->bitsPerPixel; rfbScreen->rfbServerFormat.bitsPerPixel = rfbScreen->bitsPerPixel;
rfbScreen->rfbServerFormat.depth = rfbScreen->depth; rfbScreen->rfbServerFormat.depth = rfbScreen->depth;
rfbScreen->rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest); rfbScreen->rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest);
rfbScreen->rfbServerFormat.trueColour = TRUE; rfbScreen->rfbServerFormat.trueColour = TRUE;
bitsPerSample = 8; /* Why? (TODO)
samplesPerPixel = 3;
if (samplesPerPixel != 3) { if (samplesPerPixel != 3) {
rfbLog("screen format not supported. exiting.\n"); rfbLog("screen format not supported. exiting.\n");
exit(1); exit(1);
} }
*/
/* This works for 16 and 32-bit, but not for 8-bit. /* 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?) */ What should it be for 8-bit? (Shouldn't 8-bit use a colormap?) */
...@@ -342,6 +343,14 @@ rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv) ...@@ -342,6 +343,14 @@ rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv)
rfbScreen->rfbServerFormat.redShift = bitsPerSample * 2; rfbScreen->rfbServerFormat.redShift = bitsPerSample * 2;
rfbScreen->rfbServerFormat.greenShift = bitsPerSample; rfbScreen->rfbServerFormat.greenShift = bitsPerSample;
rfbScreen->rfbServerFormat.blueShift = 0; 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 /* 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 X11 ScreenPtr, so we do this. Pretty ugly, but at least it lets us
......
...@@ -524,7 +524,7 @@ void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,RegionPtr modRegion); ...@@ -524,7 +524,7 @@ void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,RegionPtr modRegion);
void doNothingWithClient(rfbClientPtr cl); void doNothingWithClient(rfbClientPtr cl);
/* functions to make a vnc server */ /* 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); extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo);
/* call one of these two functions to service the vnc clients. /* 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