From: Peter Dinda Date: Fri, 22 Mar 2013 20:42:57 +0000 (-0500) Subject: VNC server interface to graphics console source code X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=ed2f7f63a9563dcc28ccf3ca29cf4011fa67a343 VNC server interface to graphics console source code --- diff --git a/linux_usr/Makefile b/linux_usr/Makefile index 64a2b7e..4f03c2a 100644 --- a/linux_usr/Makefile +++ b/linux_usr/Makefile @@ -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 index 0000000..1510ac5 --- /dev/null +++ b/linux_usr/vnc/Image.cxx @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "Image.h" +#include +#include +#include +#include + +class ImageCleanup { +public: + std::list 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 index 0000000..bcfaa7f --- /dev/null +++ b/linux_usr/vnc/Image.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 index 0000000..f312cfe --- /dev/null +++ b/linux_usr/vnc/Makefile @@ -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 index 0000000..e0b06cb --- /dev/null +++ b/linux_usr/vnc/Makefile.in @@ -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 index 0000000..90e5301 --- /dev/null +++ b/linux_usr/vnc/README @@ -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 index 0000000..a96031c --- /dev/null +++ b/linux_usr/vnc/buildtime.c @@ -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 index 0000000..0e51d7b --- /dev/null +++ b/linux_usr/vnc/utils.h @@ -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 index 0000000..3628f15 --- /dev/null +++ b/linux_usr/vnc/x0vncserver.cxx @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "Image.h" +#include +#include +#include +#include +#include + + +#include + + +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 [] /dev/v3-vmN \n", programName); + fprintf(stderr,"\n" + "Parameters can be turned on with - or off with -=0\n" + "Parameters which take a value can be specified as " + "- \n" + "Other valid forms are = -= " + "--=\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 sockets; + server.getSockets(&sockets); + std::list::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 index 0000000..9f81396 --- /dev/null +++ b/linux_usr/vnc/x0vncserver.man @@ -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.