From af4e02678babede037b128f9db4f0c71bf224a0f Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Tue, 14 Aug 2001 07:48:57 +0000
Subject: hooks inserted

---
 Makefile    |  4 ++--
 example.c   | 40 +++++++++++++++++++++++++++++-----------
 main.c      | 41 ++++++++++++++++-------------------------
 rfb.h       | 17 +++++++++++++++--
 rfbserver.c | 10 ++++++++--
 5 files changed, 70 insertions(+), 42 deletions(-)

diff --git a/Makefile b/Makefile
index 5ef46f7..1969adc 100644
--- a/Makefile
+++ b/Makefile
@@ -8,10 +8,10 @@ VNCAUTHLIB=-Llibvncauth -lvncauth
 VNCSERVERLIB=-L. -lvncserver -lz -ljpeg
 
 # These two lines enable useage of PThreads
-CFLAGS += -DHAVE_PTHREADS
+#CFLAGS += -DHAVE_PTHREADS
 VNCSERVERLIB += -lpthread
 
-LIBS=$(VNCSERVERLIB) $(VNCAUTHLIB)
+LIBS=$(LDFLAGS) $(VNCSERVERLIB) $(VNCAUTHLIB)
 
 # for Mac OS X
 OSX_LIBS = -framework ApplicationServices -framework Carbon
diff --git a/example.c b/example.c
index 8d6a83e..2fe1d3f 100644
--- a/example.c
+++ b/example.c
@@ -32,26 +32,49 @@
 
 const int maxx=640, maxy=480, bpp=4;
 
+void initBuffer(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);
+    }
+}
+
 void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
 {
    if(buttonMask && x>=0 && y>=0 && x<maxx && y<maxy) {
-      int i;
-      for(i=0;i<bpp;i++)
-	cl->screen->frameBuffer[y*cl->screen->paddedWidthInBytes+x*bpp+i]^=0xff;
-      rfbMarkRectAsModified(cl->screen,x,y,x+1,y+1);
+      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);
    }
 }
 
+
+
 void dokey(Bool down,KeySym key,rfbClientPtr cl)
 {
   if(down && key==XK_Escape)
     rfbCloseClient(cl);
+  else if(down && key=='c') {
+    initBuffer(cl->screen->frameBuffer);
+    rfbMarkRectAsModified(cl->screen,0,0,maxx,maxy);
+  }
 }
 
 int main(int argc,char** argv)
 {
-  int i,j;
   rfbScreenInfoPtr rfbScreen = rfbDefaultScreenInit(argc,argv);
   rfbScreen->desktopName="LibVNCServer Example";
   rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp);
@@ -61,12 +84,7 @@ int main(int argc,char** argv)
   rfbScreen->ptrAddEvent=doptr;
   rfbScreen->kbdAddEvent=dokey;
 
-  for(i=0;i<maxx;++i)
-    for(j=0;j<maxy;++j) {
-      rfbScreen->frameBuffer[(j*maxx+i)*bpp]=i*256/maxx;
-      rfbScreen->frameBuffer[(j*maxx+i)*bpp+1]=j*256/maxy;
-      rfbScreen->frameBuffer[(j*maxx+i)*bpp+2]=(i+j)*256/(maxx*maxy);
-    }
+  initBuffer(rfbScreen->frameBuffer);
 
   runEventLoop(rfbScreen,40000,FALSE);
   runEventLoop(rfbScreen,40000,TRUE);
diff --git a/main.c b/main.c
index 347784a..ef39aa4 100644
--- a/main.c
+++ b/main.c
@@ -279,32 +279,20 @@ processArguments(rfbScreenInfoPtr rfbScreen,int argc, char *argv[])
 }
 
 void
-DefaultKbdAddEvent(down, keySym, cl)
-    Bool down;
-    KeySym keySym;
-    rfbClientPtr cl;
+defaultKbdAddEvent(Bool down, KeySym keySym, rfbClientPtr cl)
 {
 }
 
 void
-DefaultPtrAddEvent(buttonMask, x, y, cl)
-    int buttonMask;
-    int x;
-    int y;
-    rfbClientPtr cl;
+defaultPtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl)
 {
 }
 
-void
-DefaultKbdReleaseAllKeys(cl)
-     rfbClientPtr cl;
+void defaultSetXCutText(char* text, int len, rfbClientPtr cl)
 {
 }
 
-void DefaultSetXCutText(text,len,cl)
-  char* text;
-  int len;
-  rfbClientPtr cl;
+void doNothingWithClient(rfbClientPtr cl)
 {
 }
 
@@ -378,10 +366,12 @@ rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv)
    rfbScreen->screen.RegionAppend = miRegionAppend;
    rfbScreen->screen.RegionValidate = miRegionValidate;
 
-   rfbScreen->kbdAddEvent = DefaultKbdAddEvent;
-   rfbScreen->kbdReleaseAllKeys = DefaultKbdReleaseAllKeys;
-   rfbScreen->ptrAddEvent = DefaultPtrAddEvent;
-   rfbScreen->setXCutText = DefaultSetXCutText;
+   rfbScreen->kbdAddEvent = defaultKbdAddEvent;
+   rfbScreen->kbdReleaseAllKeys = doNothingWithClient;
+   rfbScreen->ptrAddEvent = defaultPtrAddEvent;
+   rfbScreen->setXCutText = defaultSetXCutText;
+   rfbScreen->newClientHook = doNothingWithClient;
+
    return(rfbScreen);
 }
 
@@ -394,14 +384,15 @@ processEvents(rfbScreenInfoPtr rfbScreen,long usec)
     corbaCheckFds(rfbScreen);
 #endif
     {
-       rfbClientIteratorPtr iterator;
-       rfbClientPtr cl;
-       iterator=rfbGetClientIterator(rfbScreen);
-       while((cl=rfbClientIteratorNext(iterator)))
+       rfbClientPtr cl,cl_next;
+       cl=rfbScreen->rfbClientHead;
+       while(cl) {
+	 cl_next=cl->next;
 	 if(cl->sock>=0 && FB_UPDATE_PENDING(cl)) {
 	    rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
 	 }
-       rfbReleaseClientIterator(iterator);
+	 cl=cl_next;
+       }
     }
 }
 
diff --git a/rfb.h b/rfb.h
index 416526d..bc3a9bc 100644
--- a/rfb.h
+++ b/rfb.h
@@ -66,6 +66,8 @@ typedef void (*KbdReleaseAllKeysProcPtr) (struct rfbClientRec* cl);
 typedef void (*PtrAddEventProcPtr) (int buttonMask, int x, int y, struct rfbClientRec* cl);
 typedef void (*SetXCutTextProcPtr) (char* str,int len, struct rfbClientRec* cl);
 
+typedef void (*NewClientHookPtr)(struct rfbClientRec* cl);
+
 /*
  * Per-screen (framebuffer) structure.  There is only one of these, since we
  * don't allow the X server to have multiple screens.
@@ -167,6 +169,12 @@ typedef struct
     KbdReleaseAllKeysProcPtr kbdReleaseAllKeys;
     PtrAddEventProcPtr ptrAddEvent;
     SetXCutTextProcPtr setXCutText;
+
+    /* the following members are hooks, i.e. they are called if set,
+       but not overriding original functionality */
+    /* newClientHook is called just after a new client is created */
+    NewClientHookPtr newClientHook;
+
 } rfbScreenInfo, *rfbScreenInfoPtr;
 
 
@@ -174,7 +182,6 @@ typedef struct
  * rfbTranslateFnType is the type of translation functions.
  */
 
-struct rfbClientRec;
 typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in,
                                    rfbPixelFormat *out,
                                    char *iptr, char *optr,
@@ -186,8 +193,12 @@ typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in,
  * Per-client structure.
  */
 
+typedef void (*ClientGoneHookPtr)(struct rfbClientRec* cl);
+
 typedef struct rfbClientRec {
     rfbScreenInfoPtr screen;
+    void* clientData;
+    ClientGoneHookPtr clientGoneHook;
    
     int sock;
     char *host;
@@ -415,6 +426,8 @@ extern Bool rfbSendFramebufferUpdate(rfbClientPtr cl, RegionRec updateRegion);
 extern Bool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h);
 extern Bool rfbSendUpdateBuf(rfbClientPtr cl);
 extern void rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len);
+extern Bool rfbSendCopyRegion(rfbClientPtr cl,RegionPtr reg,int dx,int dy);
+extern Bool rfbSendLastRectMarker(rfbClientPtr cl);
 
 void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len);
 
@@ -508,7 +521,7 @@ extern void rfbDisconnectUDPSock(rfbScreenInfoPtr cl);
 
 void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2);
 void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,RegionPtr modRegion);
-
+void doNothingWithClient(rfbClientPtr cl);
 
 /* functions to make a vnc server */
 extern rfbScreenInfoPtr rfbDefaultScreenInit(int argc,char** argv);
diff --git a/rfbserver.c b/rfbserver.c
index 3a185b4..b90fb05 100644
--- a/rfbserver.c
+++ b/rfbserver.c
@@ -237,6 +237,10 @@ rfbNewClient(rfbScreen,sock)
     sprintf(pv,rfbProtocolVersionFormat,rfbProtocolMajorVersion,
             rfbProtocolMinorVersion);
 
+    cl->clientData = NULL;
+    cl->clientGoneHook = doNothingWithClient;
+    cl->screen->newClientHook(cl);
+
     if (WriteExact(cl, pv, sz_rfbProtocolVersionMsg) < 0) {
         rfbLogPerror("rfbNewClient: write");
         rfbCloseClient(cl);
@@ -261,6 +265,8 @@ rfbClientConnectionGone(cl)
     pthread_mutex_lock(&rfbClientListMutex);
 #endif
 
+    cl->clientGoneHook(cl);
+
     rfbLog("Client %s gone\n",cl->host);
     free(cl->host);
 
@@ -1052,7 +1058,7 @@ rfbSendFramebufferUpdate(cl, updateRegion)
  * of a later one.
  */
 
-static Bool
+Bool
 rfbSendCopyRegion(cl, reg, dx, dy)
     rfbClientPtr cl;
     RegionPtr reg;
@@ -1216,7 +1222,7 @@ rfbSendRectEncodingRaw(cl, x, y, w, h)
  * protocol).
  */
 
-static Bool
+Bool
 rfbSendLastRectMarker(cl)
     rfbClientPtr cl;
 {
-- 
cgit v1.2.3

