Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


VNC server interface to graphics console source code
Peter Dinda [Fri, 22 Mar 2013 20:42:57 +0000 (15:42 -0500)]
linux_usr/Makefile
linux_usr/vnc/Image.cxx [new file with mode: 0644]
linux_usr/vnc/Image.h [new file with mode: 0644]
linux_usr/vnc/Makefile [new file with mode: 0644]
linux_usr/vnc/Makefile.in [new file with mode: 0644]
linux_usr/vnc/README [new file with mode: 0644]
linux_usr/vnc/buildtime.c [new file with mode: 0644]
linux_usr/vnc/utils.h [new file with mode: 0644]
linux_usr/vnc/x0vncserver.cxx [new file with mode: 0644]
linux_usr/vnc/x0vncserver.man [new file with mode: 0644]

index 64a2b7e..4f03c2a 100644 (file)
@@ -181,6 +181,7 @@ v3_x0vncserver :
        else \
                echo "In order to use v3_vncclient/server you must have" ; \
                echo "previously built or received palacios/linux_usr/x0vncserver" ; \
+               echo "To learn more about this, look in palacios/linux_usr/vnc"; \
        fi;
 
 #
diff --git a/linux_usr/vnc/Image.cxx b/linux_usr/vnc/Image.cxx
new file mode 100644 (file)
index 0000000..1510ac5
--- /dev/null
@@ -0,0 +1,84 @@
+/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+//
+// Image.cxx
+//
+
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/stat.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+#include "Image.h"
+#include <list>
+#include <sys/ioctl.h>
+#include <unistd.h> 
+#include <fcntl.h>
+
+class ImageCleanup {
+public:
+  std::list<Image*> images;
+
+  ~ImageCleanup()
+  {
+    fprintf(stderr,"~ImageCleanup called\n");
+
+    while (!images.empty()) {
+      delete images.front();
+    }
+  }
+};
+
+ImageCleanup imageCleanup;
+
+Image::Image(int width, int height)
+  : data(0)
+{
+  data = new char[width*height*4];
+  
+  //default image will be three lines across the screen.
+  this->width = width;
+  this->height = height;
+  
+  for (int i = 0; i < width*(height/3)*4; i++) {
+    if ((i % 4) == 0){
+      data[i] = 255;
+    }
+  }
+  for (int i = width*(height/3)*4 + 1; i < width*(2*height/3)*4; i++) {
+    if (((i + 3) % 4) == 0){
+      data[i] = 255;
+    }
+  }
+  for (int i = width*(2*height/3)*4 + 1; i < width*(height)*4; i++) {
+    if (((i + 2) % 4) == 0){
+      data[i] = 255;
+    }
+  }    
+}
+
+Image::~Image()
+{
+  delete [] data;
+}
+
diff --git a/linux_usr/vnc/Image.h b/linux_usr/vnc/Image.h
new file mode 100644 (file)
index 0000000..bcfaa7f
--- /dev/null
@@ -0,0 +1,52 @@
+/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+//
+// Image.h
+//
+
+#ifndef __IMAGE_H__
+#define __IMAGE_H__
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/stat.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/ioctl.h>
+#include <unistd.h> 
+#include <fcntl.h>
+
+class Image {
+
+public:
+
+  Image(int width, int height);
+  ~Image();
+
+  char* data;
+
+private:
+
+  int height;
+  int width;
+};
+
+#endif
diff --git a/linux_usr/vnc/Makefile b/linux_usr/vnc/Makefile
new file mode 100644 (file)
index 0000000..f312cfe
--- /dev/null
@@ -0,0 +1,60 @@
+# Generated automatically from Makefile.in:boilerplate.mk by configure.
+
+V3FB_DIR = ../../palacios/linux_usr
+
+SRCS = Image.cxx x0vncserver.cxx
+
+OBJS = $(SRCS:.cxx=.o)  $(CSRCS:.c=.o)
+
+program = x0vncserver
+
+DEP_LIBS = ../rfb/librfb.a ../network/libnetwork.a ../rdr/librdr.a
+
+EXTRA_LIBS = $(top_srcdir)/zlib/libz.a  -L/usr/lib64 $(top_srcdir)/Xregion/libXregion.a $(top_srcdir)/xlib/libX11.a $(top_srcdir)/xlib/libSM.a $(top_srcdir)/xlib/libICE.a $(top_srcdir)/xlib/libXtst.a $(top_srcdir)/xlib/libXext.a -L$(V3FB_DIR) -lv3_fb # -lX11 -lSM -lICE  -lXtst -lXext 
+
+DIR_CPPFLAGS = -I$(top_srcdir)  -I$(V3FB_DIR) # X_CFLAGS are really CPPFLAGS
+
+all:: $(program)
+
+$(program): $(OBJS) buildtime.o $(DEP_LIBS)
+       rm -f $(program)
+       $(CXXLD) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJS) buildtime.o $(DEP_LIBS) $(LIBS) $(EXTRA_LIBS)
+
+buildtime.o: $(OBJS) $(DEP_LIBS)
+
+# followed by boilerplate.mk
+
+all::
+       @subdirs="$(SUBDIRS)"; for d in $$subdirs; do (cd $$d; $(MAKE) $@) || exit 1; done
+
+clean::
+       @subdirs="$(SUBDIRS)"; for d in $$subdirs; do (cd $$d; $(MAKE) $@) || exit 1; done
+
+clean::
+       rm -f $(program) $(library) *.o
+
+SHELL = /bin/sh
+top_srcdir = ..
+
+CC = gcc
+CFLAGS = -g $(DIR_CFLAGS) #-O2 -Wall 
+CCLD = $(CC)
+CXX = c++
+CXXFLAGS = -g #-O2 -Wall
+CXXLD = $(CXX)
+CPPFLAGS = 
+DEFS =  
+ALL_CPPFLAGS = $(CPPFLAGS) $(DEFS) $(DIR_CPPFLAGS)
+LIBS = 
+LDFLAGS = --whole-archive --static
+RANLIB = ranlib
+AR = ar cq
+
+.SUFFIXES:
+.SUFFIXES: .cxx .c .o
+
+.c.o:
+       $(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c $<
+
+.cxx.o:
+       $(CXX) $(ALL_CPPFLAGS) $(CXXFLAGS) -c $<
diff --git a/linux_usr/vnc/Makefile.in b/linux_usr/vnc/Makefile.in
new file mode 100644 (file)
index 0000000..e0b06cb
--- /dev/null
@@ -0,0 +1,22 @@
+
+SRCS = Image.cxx x0vncserver.cxx
+
+OBJS = $(SRCS:.cxx=.o)
+
+program = x0vncserver
+
+DEP_LIBS = ../rfb/librfb.a ../network/libnetwork.a ../rdr/librdr.a
+
+EXTRA_LIBS = @ZLIB_LIB@ @X_PRE_LIBS@ @X_LIBS@ -lXtst -lXext -lX11 @X_EXTRA_LIBS@
+
+DIR_CPPFLAGS = -I$(top_srcdir) @X_CFLAGS@ # X_CFLAGS are really CPPFLAGS
+
+all:: $(program)
+
+$(program): $(OBJS) buildtime.o $(DEP_LIBS)
+       rm -f $(program)
+       $(CXXLD) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJS) buildtime.o $(DEP_LIBS) $(LIBS) $(EXTRA_LIBS)
+
+buildtime.o: $(OBJS) $(DEP_LIBS)
+
+# followed by boilerplate.mk
diff --git a/linux_usr/vnc/README b/linux_usr/vnc/README
new file mode 100644 (file)
index 0000000..90e5301
--- /dev/null
@@ -0,0 +1,39 @@
+This directory contains the sources for a VNC server designed for use
+with the Graphics Console interface.   It is a variant of the x0vncserver
+that ships with the VNC sources.  It's used with the following flow:
+
+  any vncclient
+      |
+ this x0vncserver
+      |
+graphics console userspace interface
+      |
+virtual device (vga.c, paragraph.c, ...)
+      |
+    guest
+
+Building VNC tools generally needs to be done in the context
+of the VNC distribution.    You cannot compile here.  You
+want to build this in the following way:
+
+0. build palacios/linux_usr to give you libv3_fb.a
+1. get a copy of the VNC distro - this is based on 4.0
+2. configure and build the whole thing
+3. you'll notice that the VNC distro has a x0vncserver
+   directory/target.   This directory needs to either
+   replace it, patch it, or go alongside it.
+   Notice that VNC generates Makefiles as part of configuration.
+4. modify the Makefile to reflect the one seen here. 
+   namely, you will want the following:
+
+V3FB_DIR = path/to/palacios/linux_usr
+
+EXTRA_LIBS += -L$(V3FB_DIR) -lv3_fb
+
+DIR_CPPFLAGS +=  -I$(V3FB_DIR)
+
+5. build x0vncserver
+6. cp x0vncserver palacios/linux_usr
+7. cd palacios/linux_usr; make v3_x0vncserver
+
+
diff --git a/linux_usr/vnc/buildtime.c b/linux_usr/vnc/buildtime.c
new file mode 100644 (file)
index 0000000..a96031c
--- /dev/null
@@ -0,0 +1,18 @@
+/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+char buildtime[] = __DATE__ " " __TIME__;
diff --git a/linux_usr/vnc/utils.h b/linux_usr/vnc/utils.h
new file mode 100644 (file)
index 0000000..0e51d7b
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __UTILS_H__
+#define __UTILS_H__
+
+struct framebuffer {
+  int length;
+  char *buffer;
+};
+
+#endif
diff --git a/linux_usr/vnc/x0vncserver.cxx b/linux_usr/vnc/x0vncserver.cxx
new file mode 100644 (file)
index 0000000..3628f15
--- /dev/null
@@ -0,0 +1,526 @@
+/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+#include <strings.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <rfb/Logger_stdio.h>
+#include <rfb/LogWriter.h>
+#include <rfb/VNCServerST.h>
+#include <rfb/Configuration.h>
+#include <rfb/SSecurityFactoryStandard.h>
+
+#include <network/TcpSocket.h>
+
+#include "Image.h"
+#include <signal.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XTest.h>
+
+
+#include <rfb/Encoder.h>
+
+
+using namespace rfb;
+using namespace rdr;
+using namespace network;
+
+#include "v3_fb.h"
+
+
+
+#define NO_KEY { 0, 0 }
+
+struct key_code {
+    uint8_t scan_code;
+    uint8_t capital;
+};
+
+
+static const struct key_code ascii_to_key_code[] = {             // ASCII Value Serves as Index
+    NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x00 - 0x03
+    NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x04 - 0x07
+    { 0x0E, 0 },    { 0x0F, 0 },    { 0x1C, 0 },    NO_KEY,      // 0x08 - 0x0B
+    NO_KEY,         { 0x1C, 0 },    NO_KEY,         NO_KEY,      // 0x0C - 0x0F
+    NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x10 - 0x13
+    NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x14 - 0x17
+    NO_KEY,         NO_KEY,         NO_KEY,         { 0x01, 0 }, // 0x18 - 0x1B
+    NO_KEY,         NO_KEY,         NO_KEY,         NO_KEY,      // 0x1C - 0x1F
+    { 0x39, 0 },    { 0x02, 1 },    { 0x28, 1 },    { 0x04, 1 }, // 0x20 - 0x23
+    { 0x05, 1 },    { 0x06, 1 },    { 0x08, 1 },    { 0x28, 0 }, // 0x24 - 0x27
+    { 0x0A, 1 },    { 0x0B, 1 },    { 0x09, 1 },    { 0x0D, 1 }, // 0x28 - 0x2B
+    { 0x33, 0 },    { 0x0C, 0 },    { 0x34, 0 },    { 0x35, 0 }, // 0x2C - 0x2F
+    { 0x0B, 0 },    { 0x02, 0 },    { 0x03, 0 },    { 0x04, 0 }, // 0x30 - 0x33
+    { 0x05, 0 },    { 0x06, 0 },    { 0x07, 0 },    { 0x08, 0 }, // 0x34 - 0x37
+    { 0x09, 0 },    { 0x0A, 0 },    { 0x27, 1 },    { 0x27, 0 }, // 0x38 - 0x3B
+    { 0x33, 1 },    { 0x0D, 0 },    { 0x34, 1 },    { 0x35, 1 }, // 0x3C - 0x3F
+    { 0x03, 1 },    { 0x1E, 1 },    { 0x30, 1 },    { 0x2E, 1 }, // 0x40 - 0x43
+    { 0x20, 1 },    { 0x12, 1 },    { 0x21, 1 },    { 0x22, 1 }, // 0x44 - 0x47
+    { 0x23, 1 },    { 0x17, 1 },    { 0x24, 1 },    { 0x25, 1 }, // 0x48 - 0x4B
+    { 0x26, 1 },    { 0x32, 1 },    { 0x31, 1 },    { 0x18, 1 }, // 0x4C - 0x4F
+    { 0x19, 1 },    { 0x10, 1 },    { 0x13, 1 },    { 0x1F, 1 }, // 0x50 - 0x53
+    { 0x14, 1 },    { 0x16, 1 },    { 0x2F, 1 },    { 0x11, 1 }, // 0x54 - 0x57
+    { 0x2D, 1 },    { 0x15, 1 },    { 0x2C, 1 },    { 0x1A, 0 }, // 0x58 - 0x5B
+    { 0x2B, 0 },    { 0x1B, 0 },    { 0x07, 1 },    { 0x0C, 1 }, // 0x5C - 0x5F
+    { 0x29, 0 },    { 0x1E, 0 },    { 0x30, 0 },    { 0x2E, 0 }, // 0x60 - 0x63
+    { 0x20, 0 },    { 0x12, 0 },    { 0x21, 0 },    { 0x22, 0 }, // 0x64 - 0x67
+    { 0x23, 0 },    { 0x17, 0 },    { 0x24, 0 },    { 0x25, 0 }, // 0x68 - 0x6B
+    { 0x26, 0 },    { 0x32, 0 },    { 0x31, 0 },    { 0x18, 0 }, // 0x6C - 0x6F
+    { 0x19, 0 },    { 0x10, 0 },    { 0x13, 0 },    { 0x1F, 0 }, // 0x70 - 0x73
+    { 0x14, 0 },    { 0x16, 0 },    { 0x2F, 0 },    { 0x11, 0 }, // 0x74 - 0x77
+    { 0x2D, 0 },    { 0x15, 0 },    { 0x2C, 0 },    { 0x1A, 1 }, // 0x78 - 0x7B
+    { 0x2B, 1 },    { 0x1B, 1 },    { 0x29, 1 },    { 0x0E, 0 }  // 0x7C - 0x7F
+};
+
+static uint8_t convert_to_scancode(rdr::U32 key, bool down)
+{
+    
+
+    unsigned char scancode=0;
+
+    if (key<0x80) { 
+       struct key_code c = ascii_to_key_code[key];
+       scancode=c.scan_code;
+    } else {
+       switch (key) { 
+           case 0xffe1:  //left shift
+               scancode = 0x2a;
+               break;
+
+           case 0xffe2:  //right shift
+               scancode = 0x36;
+               break;
+
+           case 0xffe3:  //left ctrl
+           case 0xffe4:  //right ctrl
+               scancode = 0x1d;   // translated as left ctrl
+               break;
+
+           case 0xffe7:  //left meta
+           case 0xffe8:  //right meta
+           case 0xffe9:  //left alt
+           case 0xffea:  //right alt
+               scancode = 0x38;  // translated as a left alt
+               break; 
+
+           case 0xff08: // backspace
+               scancode = 0x0e;
+               break; 
+
+           case 0xff09: // tab
+               scancode = 0x0f;  
+               break; 
+
+           case 0xff0d: // return
+               scancode = 0x1c;
+               break; 
+
+           case 0xff1b: // escape
+               scancode = 0x01;
+               break; 
+
+           case 0xff63: // insert
+               scancode = 0x52;
+               break; 
+
+           case 0xffff: // delete
+               scancode = 0x53;
+               break; 
+
+           case 0xff50: // home
+               scancode = 0x47;
+               break; 
+
+           case 0xff57: // end
+               scancode = 0x4f;
+               break; 
+               
+           case 0xff55: // pageup
+               scancode = 0x49;
+               break; 
+
+           case 0xff56: // pagedown
+               scancode = 0x51;
+               break; 
+
+           case 0xff51: // left
+               scancode = 0x4b;
+               break; 
+
+           case 0xff52: // up
+               scancode = 0x48;
+               break; 
+
+           case 0xff53: // right
+               scancode = 0x4d;
+               break; 
+
+           case 0xff54: // down
+               scancode = 0x50;
+               break; 
+
+           case 0xffbe: // f1
+               scancode = 0x3b;
+               break; 
+           case 0xffbf: // f2
+               scancode = 0x3c;
+               break; 
+           case 0xffc0: // f3
+               scancode = 0x3d;
+               break; 
+           case 0xffc1: // f4
+               scancode = 0x3e;
+               break; 
+           case 0xffc2: // f5
+               scancode = 0x3f;
+               break; 
+           case 0xffc3: // f6
+               scancode = 0x40;
+               break; 
+           case 0xffc4: // f7
+               scancode = 0x41;
+               break; 
+           case 0xffc5: // f8
+               scancode = 0x42;
+               break; 
+           case 0xffc6: // f9
+               scancode = 0x43;
+               break;
+           case 0xffc7: // f10
+               scancode = 0x44;
+               break; 
+           case 0xffc8: // f11
+               scancode = 0x57;
+               break; 
+           case 0xffc9: // f12
+               scancode = 0x58;
+               break; 
+
+
+           default:
+               scancode = 0;
+               fprintf(stderr,"Ignoring key 0x%x (down=%d)\n", key, down);
+       }
+    }
+    
+    if (scancode==0) { 
+       return 0;
+    }
+
+    if (!down) { 
+       scancode|=0x80;
+    }
+    
+    return scancode;
+}
+
+       
+       
+       
+    
+
+
+
+LogWriter vlog("main");
+
+StringParameter displayname("display", "The X display", "");
+IntParameter rfbport("rfbport", "TCP port to listen for RFB protocol",5900);
+StringParameter geometry("geometry", "Height and width", "1024x768");
+
+VncAuthPasswdFileParameter vncAuthPasswdFile;
+
+static void CleanupSignalHandler(int sig)
+{
+  // CleanupSignalHandler allows C++ object cleanup to happen because it calls
+  // exit() rather than the default which is to abort.
+  fprintf(stderr,"CleanupSignalHandler called\n");
+  exit(1);
+}
+
+
+class V3Desktop : public SDesktop, public rfb::ColourMap
+{
+public:
+    V3Desktop(int fd)  // fd is the open fd of the VM's device
+    : v3_fd(fd), pb(0), server(0), oldButtonMask(0)
+    {
+    
+      // Let's get the needed resolution
+      if (v3_get_fb_spec(v3_fd,&v3_spec)) { 
+         fprintf(stderr, "Can't get spec from VM\n");
+         exit(-1);
+      }
+
+      // sanity check:
+      fprintf(stderr,"VM's spec is %u x %u x %u with %u bits per channel and rgb offsets (%u,%u,%u)\n",
+             v3_spec.width, v3_spec.height, v3_spec.bytes_per_pixel, 
+             v3_spec.bits_per_channel, v3_spec.red_offset, v3_spec.green_offset, v3_spec.blue_offset);
+
+      if (! (v3_spec.bytes_per_pixel==4 &&
+            v3_spec.bits_per_channel==8)) { 
+         fprintf(stderr,"Error in forma compatabiliity\n");
+         exit(-1);
+      }
+
+      dpyWidth=v3_spec.width;
+      dpyHeight=v3_spec.height;
+      
+      // Now we can build our image to match
+      image = new Image(dpyWidth, dpyHeight);
+
+      // Convert to the internal pixel format a
+      pf.bpp = v3_spec.bytes_per_pixel*8;
+      pf.depth = v3_spec.bits_per_channel*3;
+      pf.bigEndian = 0;
+      pf.trueColour = 1;
+    
+      //default pixel formats dont work!
+      pf.redShift   = v3_spec.red_offset*8;
+      pf.greenShift = v3_spec.green_offset*8;
+      pf.blueShift  = v3_spec.blue_offset*8;
+      pf.redMax     = 255;
+      pf.greenMax   = 255;
+      pf.blueMax    = 255;
+    
+      // assigns new pixelbuffer to xdesktop object
+      pb = new FullFramePixelBuffer(pf, dpyWidth, dpyHeight,
+                                   (rdr::U8*)image->data, this);
+    }
+
+    virtual ~V3Desktop() {
+       delete pb;
+       delete image;
+    }
+    
+    void setVNCServer(VNCServer* s) {
+       server = s;
+       server->setPixelBuffer(pb);
+    }
+    
+    // -=- SDesktop interface, worry about the pointer and key events later..
+    virtual void pointerEvent(const Point& pos, rdr::U8 buttonMask) {
+       vlog.info("Pointer event occurred, x position: %d, y position: %d; button mask: %d.", pos.x, pos.y, buttonMask); 
+       if (v3_send_mouse(v3_fd,pos.x,pos.y,buttonMask)) { 
+           fprintf(stderr, "Error in sending mouse event\n");
+           exit(-1);
+       }
+    }
+    
+    virtual void keyEvent(rdr::U32 key, bool down) {
+       vlog.info("Key event received (key=%d, down=%d.",key,down);
+    
+       //STILL NEED TO FIND MAPPING FROM KEYSYM TO ACTUAL KEYSTROKES    
+       uint8_t scan_code = convert_to_scancode(key,down);
+
+       if (scan_code && v3_send_key(v3_fd,scan_code)) {
+           fprintf(stderr, "Error in sending key event\n");
+           exit(-1);
+       }
+       
+    }
+  
+    virtual void clientCutText(const char* str, int len) {
+    }
+    
+    virtual Point getFbSize() {
+       return Point(pb->width(), pb->height());
+    }
+
+    virtual void lookup(int index, int* r, int* g, int* b) {
+    
+       // Probably not important since we will use true-color
+
+       /* X implementation..
+          XColor xc;
+          xc.pixel = index;
+          if (index < DisplayCells(dpy,DefaultScreen(dpy))) {
+          XQueryColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), &xc);
+          } else {
+          xc.red = xc.green = xc.blue = 0;
+          }
+          *r = xc.red;
+          *g = xc.green;
+          *b = xc.blue;
+          */
+    }
+    
+    virtual void poll() {
+       if (server && 
+           server->clientsReadyForUpdate() && 
+           v3_have_update(v3_fd)) {
+
+           struct v3_frame_buffer_spec newspec = v3_spec;
+
+           if (v3_get_fb_data(v3_fd,&newspec,image->data)<0) { 
+               fprintf(stderr,"Failed to get fb data from VM\n");
+               exit(-1);
+           }
+
+           if (memcmp(&newspec,&v3_spec,sizeof(struct v3_frame_buffer_spec))) { 
+               fprintf(stderr,"Uh oh - screen spec has changed\n");
+               exit(-1);
+           }
+           
+           fprintf(stderr,"render!\n");
+
+           server->add_changed(pb->getRect());
+           server->tryUpdate();
+       }
+    }
+    
+protected:
+    int v3_fd;
+    struct v3_frame_buffer_spec v3_spec;
+    
+    PixelFormat pf;
+    PixelBuffer* pb;
+    VNCServer* server;
+    Image* image;
+    int oldButtonMask;
+    bool haveXtest;
+    int dpyHeight;
+    int dpyWidth;
+};
+
+char* programName;
+
+static void usage()
+{
+  fprintf(stderr, "\nusage: %s [<parameters>] /dev/v3-vmN \n", programName);
+  fprintf(stderr,"\n"
+          "Parameters can be turned on with -<param> or off with -<param>=0\n"
+          "Parameters which take a value can be specified as "
+          "-<param> <value>\n"
+          "Other valid forms are <param>=<value> -<param>=<value> "
+          "--<param>=<value>\n"
+          "Parameter names are case-insensitive.  The parameters are:\n\n");
+  Configuration::listParams(79, 14);
+  exit(1);
+}
+
+int main(int argc, char** argv)
+{
+  int v3_fd;
+  char *v3_dev;
+
+  initStdIOLoggers();
+  LogWriter::setLogParams("*:stderr:30");
+
+  programName = argv[0];
+
+  // Grab the v3 device before all the OO stuff goes inscrutable on us
+  if (argc<2) { 
+      usage();
+  }
+  v3_dev = argv[argc-1];
+  argc--;
+  fprintf(stderr,"Will attempt to connect to VM %s\n",v3_dev);
+
+
+
+
+  Display* dpy;
+
+  for (int i = 1; i < argc; i++) {
+    if (Configuration::setParam(argv[i]))
+      continue;
+
+    if (argv[i][0] == '-') {
+      if (i+1 < argc) {
+        if (Configuration::setParam(&argv[i][1], argv[i+1])) {
+          i++;
+          continue;
+        }
+      }
+      usage();
+    }
+
+    usage();
+  }
+
+  CharArray dpyStr(displayname.getData());
+  dpy = NULL;
+
+  signal(SIGHUP, CleanupSignalHandler);
+  signal(SIGINT, CleanupSignalHandler);
+  signal(SIGTERM, CleanupSignalHandler);
+
+  try {
+    v3_fd = open(v3_dev, O_RDONLY);    
+
+    if (v3_fd<0) { 
+       perror("Cannot open VM");
+       exit(-1);
+    }
+  
+    V3Desktop desktop(v3_fd);
+    VNCServerST server("v3x0vncserver", &desktop);
+    desktop.setVNCServer(&server);
+
+    TcpSocket::initTcpSockets();
+    TcpListener listener((int)rfbport);
+    vlog.info("Listening on port %d", (int)rfbport);
+    
+    while (true) {
+      fd_set rfds;
+      struct timeval tv;
+
+      tv.tv_sec = 0;
+      tv.tv_usec = 50*1000;
+
+      FD_ZERO(&rfds);
+      FD_SET(listener.getFd(), &rfds);
+
+      std::list<Socket*> sockets;
+      server.getSockets(&sockets);
+      std::list<Socket*>::iterator i;
+      for (i = sockets.begin(); i != sockets.end(); i++) {
+        FD_SET((*i)->getFd(), &rfds);
+      }
+
+      int n = select(FD_SETSIZE, &rfds, 0, 0, &tv);
+      if (n < 0) throw rdr::SystemException("select",errno);
+
+      if (FD_ISSET(listener.getFd(), &rfds)) {
+        Socket* sock = listener.accept();
+        server.addClient(sock);
+      }
+
+      server.getSockets(&sockets);
+      for (i = sockets.begin(); i != sockets.end(); i++) {
+        if (FD_ISSET((*i)->getFd(), &rfds)) {
+          server.processSocketEvent(*i);
+        }
+      }
+
+      server.checkTimeouts();
+      desktop.poll();
+    }
+
+  } catch (rdr::Exception &e) {
+    vlog.error(e.str());
+    close(v3_fd);
+  };
+
+  close(v3_fd);
+
+  return 0;
+}
diff --git a/linux_usr/vnc/x0vncserver.man b/linux_usr/vnc/x0vncserver.man
new file mode 100644 (file)
index 0000000..9f81396
--- /dev/null
@@ -0,0 +1,32 @@
+.TH x0vncserver 1 "19 September 2003" "RealVNC Ltd" "Virtual Network Computing"
+.SH NAME
+x0vncserver \- VNC server which continuously polls an X display
+.SH SYNOPSIS
+.B x0vncserver
+[\fIparameters\fP]
+.SH DESCRIPTION
+.B x0vncserver
+is a VNC server which continuously polls any X display, allowing it to be
+controlled via VNC.  How usable it will be depends a lot on the machine it's
+running on, and what you're expecting.  It won't be as fast as Xvnc or a native
+X server with VNC support compiled in, but in many cases it is the best option
+since it is just an ordinary X application requiring no special installation.
+
+It has many of the same parameters as Xvnc.  Running \fBx0vncserver -h\fP will
+give a list of parameters with descriptions.  Note that you need to explicitly
+specify an appropriate password file using the PasswordFile parameter.
+
+.SH SEE ALSO
+.BR Xvnc (1)
+.BR vncpasswd (1),
+.BR vncviewer (1),
+.BR vncserver (1),
+.br
+http://www.realvnc.com
+
+.SH AUTHOR
+Tristan Richardson, RealVNC Ltd.
+
+VNC was originally developed by the RealVNC team while at Olivetti Research Ltd
+/ AT&T Laboratories Cambridge.  It is now being maintained by RealVNC Ltd.  See
+http://www.realvnc.com for details.