From d44e3af64b3e224cdc2cba2549a9e84caefc2137 Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Thu, 18 Oct 2001 23:37:30 +0000
Subject: add rfbDrawLine, rfbDrawPixel and vncev, an xev "lookalike"

---
 Makefile |   3 ++
 TODO     |   1 +
 draw.c   |  47 ++++++++++++++++++++++++-
 main.c   |   3 ++
 rfb.h    |   3 ++
 vncev.c  | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 175 insertions(+), 1 deletion(-)
 create mode 100644 vncev.c

diff --git a/Makefile b/Makefile
index 64fe312..26b88b1 100644
--- a/Makefile
+++ b/Makefile
@@ -76,6 +76,9 @@ pnmshow24: pnmshow24.o libvncserver.a
 fontsel: fontsel.o libvncserver.a
 	$(CC) -o fontsel fontsel.o -L. -lvncserver -lz -ljpeg
 
+vncev: vncev.o libvncserver.a
+	$(CC) -o vncev vncev.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/TODO b/TODO
index 4e6b3de..522481b 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,7 @@
 immediate:
 ----------
 
+in keysym tester mouse buttons make copy rect, but text is not marked as mod.
 cursor drawing: set optional grain to mark bigger rectangles as drawn (else
 	you end up with thousands of one-pixel-rectangles to encode).
 selectbox: scroll bars
diff --git a/draw.c b/draw.c
index df30d5d..24c41bd 100644
--- a/draw.c
+++ b/draw.c
@@ -6,7 +6,7 @@ void rfbFillRect(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,Pixel col)
   int i,j;
   char* colour=(char*)&col;
 
-  if(!rfbEndianTest)
+   if(!rfbEndianTest)
     colour += 4-bpp;
   for(j=y1;j<y2;j++)
     for(i=x1;i<x2;i++)
@@ -14,3 +14,48 @@ void rfbFillRect(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,Pixel col)
   rfbMarkRectAsModified(s,x1,y1,x2,y2);
 }
 
+#define SETPIXEL(x,y) \
+  memcpy(s->frameBuffer+(y)*rowstride+(x)*bpp,colour,bpp)
+
+void rfbDrawPixel(rfbScreenInfoPtr s,int x,int y,Pixel col)
+{
+  int rowstride = s->paddedWidthInBytes, bpp = s->bitsPerPixel>>3;
+  char* colour=(char*)&col;
+
+  if(!rfbEndianTest)
+    colour += 4-bpp;
+  SETPIXEL(x,y);
+  rfbMarkRectAsModified(s,x,y,x+1,y+1);
+}
+
+void rfbDrawLine(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,Pixel col)
+{
+  int rowstride = s->paddedWidthInBytes, bpp = s->bitsPerPixel>>3;
+  int i;
+  char* colour=(char*)&col;
+
+  if(!rfbEndianTest)
+    colour += 4-bpp;
+
+#define SWAPPOINTS { i=x1; x1=x2; x2=i; i=y1; y1=y2; y2=i; }
+  if(abs(x1-x2)<abs(y1-y2)) {
+    if(y1>y2)
+      SWAPPOINTS
+    for(i=y1;i<=y2;i++)
+      SETPIXEL(x1+(i-y1)*(x2-x1)/(y2-y1),i);
+    /* TODO: Maybe make this more intelligently? */
+    if(x2<x1) { i=x1; x1=x2; x2=i; }
+    rfbMarkRectAsModified(s,x1,y1,x2+1,y2+1);
+  } else {
+    if(x1>x2)
+      SWAPPOINTS
+    else if(x1==x2) {
+      rfbDrawPixel(s,x1,y1,col);
+      return;
+    }
+    for(i=x1;i<=x2;i++)
+      SETPIXEL(i,y1+(i-x1)*(y2-y1)/(x2-x1));
+    if(y2<y1) { i=y1; y1=y2; y2=i; }
+    rfbMarkRectAsModified(s,x1,y1,x2+1,y2+1);
+  }
+}
diff --git a/main.c b/main.c
index db705ed..84dfde6 100644
--- a/main.c
+++ b/main.c
@@ -346,6 +346,9 @@ processArguments(rfbScreenInfoPtr rfbScreen,int argc, char *argv[])
         } 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];
diff --git a/rfb.h b/rfb.h
index eac85e2..aee123c 100644
--- a/rfb.h
+++ b/rfb.h
@@ -702,7 +702,10 @@ void rfbFreeFont(rfbFontDataPtr font);
 
 /* draw.c */
 
+/* You have to call rfbUndrawCursor before using these functions */
 void rfbFillRect(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,Pixel col);
+void rfbDrawPixel(rfbScreenInfoPtr s,int x,int y,Pixel col);
+void rfbDrawLine(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,Pixel col);
 
 /* selbox.c */
 
diff --git a/vncev.c b/vncev.c
new file mode 100644
index 0000000..ca3b379
--- /dev/null
+++ b/vncev.c
@@ -0,0 +1,119 @@
+/* This program is a simple server to show events coming from the client */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include "rfb.h"
+#include "default8x16.h"
+
+char f[640*480];
+char* keys[0x400];
+
+int hex2number(unsigned char c)
+{
+   if(c>'f') return(-1);
+   else if(c>'F')
+     return(10+c-'a');
+   else if(c>'9')
+     return(10+c-'A');
+   else
+     return(c-'0');
+}
+
+void read_keys()
+{
+   int i,j,k;
+   char buffer[1024];
+   FILE* keysyms=fopen("keysym.h","r");
+
+   memset(keys,0,0x400*sizeof(char*));
+   
+   if(!keysyms)
+     return;
+   
+   while(!feof(keysyms)) {
+      fgets(buffer,1024,keysyms);
+      if(!strncmp(buffer,"#define XK_",strlen("#define XK_"))) {
+	 for(i=strlen("#define XK_");buffer[i] && buffer[i]!=' '
+	     && buffer[i]!='\t';i++);
+	 if(buffer[i]==0) /* don't support wrapped lines */
+	   continue;
+	 buffer[i]=0;
+	 for(i++;buffer[i] && buffer[i]!='0';i++);
+	 if(buffer[i]==0 || buffer[i+1]!='x') continue;
+	 for(j=0,i+=2;(k=hex2number(buffer[i]))>=0;i++)
+	   j=j*16+k;
+	 if(keys[j&0x3ff]) {
+	    char* x=malloc(1+strlen(keys[j&0x3ff])+1+strlen(buffer+strlen("#define ")));
+	    strcpy(x,keys[j&0x3ff]);
+	    strcat(x,",");
+	    strcat(x,buffer+strlen("#define "));
+	    free(keys[j&0x3ff]);
+	    keys[j&0x3ff]=x;
+	 } else
+	   keys[j&0x3ff] = strdup(buffer+strlen("#define "));
+      }
+      
+   }
+   fclose(keysyms);
+}
+
+int lineHeight=16,lineY=480-16;
+void output(rfbScreenInfoPtr s,char* line)
+{
+   rfbDoCopyRect(s,0,0,640,480-lineHeight,0,-lineHeight);
+   rfbDrawString(s,&default8x16Font,10,lineY,line,0x01);
+   fprintf(stderr,"%s\n",line);
+}
+
+void dokey(Bool down,KeySym k,rfbClientPtr cl)
+{
+   char buffer[1024];
+   
+   sprintf(buffer,"%s: %s (0x%x)",
+	   down?"down":"up",keys[k&0x3ff]?keys[k&0x3ff]:"",k);
+   output(cl->screen,buffer);
+}
+
+void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
+{
+   char buffer[1024];
+   if(buttonMask) {
+      sprintf(buffer,"Ptr: mouse button mask 0x%x at %d,%d",buttonMask,x,y);
+      output(cl->screen,buffer);
+   }
+   
+}
+
+void newclient(rfbClientPtr cl)
+{
+   char buffer[1024];
+   struct sockaddr_in addr;
+   int len=sizeof(addr),ip;
+   
+   getpeername(cl->sock,&addr,&len);
+   ip=ntohl(addr.sin_addr.s_addr);
+   sprintf(buffer,"Client connected from ip %d.%d.%d.%d",
+	   (ip>>24)&0xff,(ip>>16)&0xff,(ip>>8)&0xff,ip&0xff);
+   output(cl->screen,buffer);
+}
+
+int main(int argc,char** argv)
+{
+   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";
+   s->rfbServerFormat.trueColour=FALSE;
+   s->frameBuffer=f;
+   s->kbdAddEvent=dokey;
+   s->ptrAddEvent=doptr;
+   s->newClientHook=newclient;
+   
+   memset(f,0,640*480);
+   read_keys();
+   rfbInitServer(s);
+   
+   while(1) {
+      rfbProcessEvents(s,999999);
+   }
+}
-- 
cgit v1.2.3

