LibVNCServer: a library for easy implementation of a RDP/VNC server. Copyright (C) 2001 Johannes E. Schindelin What is it? ----------- VNC is set of programs using the RFB (Remote Frame Buffer) protocol. They are designed to "export" a frame buffer via net. It is already in wide use for administration, but it is not that easy to make a server yourself. This has been changed by LibVNCServer. There are two examples included: - example, a shared scribble sheet - pnmshow, a program to show PNMs (pictures) over the net. The examples are not too well documented, but easy straight forward and a good starting point. How to use ---------- To make a server, you just have to initialise a server structure using the function rfbDefaultScreenInit, like rfbScreenInfoPtr rfbScreen = rfbGetScreen(argc,argv,maxx,maxy,8,3,bpp); You then can set hooks and io functions (see below) or other options (see below). After that, you initialize the server, like rfbInitServer(rfbScreen); You can use a blocking event loop, a background (pthread based) event loop, or implement your own using the rfbProcessEvents function. Making it interactive --------------------- Input is handled by IO functions (see below). Whenever you change something in the frame buffer, call rfbMarkRectAsModified. You should make sure that the cursor is not drawn before drawing yourself by calling rfbUndrawCursor. You can also draw the cursor using rfbDrawCursor, but it hardly seems necessary. For cursor details, see below. Utility functions ----------------- Whenever you draw something, you have to call rfbMarkRectAsModified(screen,x1,y1,x2,y2). This tells LibVNCServer to send updates to all connected clients. Before you draw something, be sure to call rfbUndrawCursor(cl). This tells LibVNCServer to hide the cursor. Remark: There are vncviewers out there, which know a cursor encoding, so that network traffic is low, and also the cursor doesn't need to be drawn the cursor everytime an update is sent. LibVNCServer handles all the details. Just set the cursor and don't bother any more. What is the difference between rfbScreenInfoPtr and rfbClientPtr? ----------------------------------------------------------------- The rfbScreenInfoPtr is a pointer to a rfbScreenInfo structure, which holds information about the server, like pixel format, io functions, frame buffer etc. The rfbClientPtr is a pointer to an rfbClientRec structure, which holds information about a client, like pixel format, socket of the connection, etc. A server can have several clients, but needn't have any. So, if you have a server and three clients are connected, you have one instance of a rfbScreenInfo and three instances of rfbClientRec's. The rfbClientRec structure holds a member rfbScreenInfoPtr screen which points to the server and a member rfbClientPtr next to the next client. The rfbScreenInfo structure holds a member rfbClientPtr rfbClientHead which points to the first client. So, to access the server from the client structure, you use client->screen. To access all clients from a server, get screen->rfbClientHead and iterate using client->next. If you change client settings, be sure to use the provided iterator rfbGetClientIterator(rfbScreen) with rfbClientIteratorNext(iterator) and rfbReleaseClientIterator to prevent thread clashes. Other options ------------- These options have to be set between rfbGetScreen and rfbInitServer. If you already have a socket to talk to, just set rfbScreen->inetdSock (originally this is for inetd handling, but why not use it for your purpose?). To also start an HTTP server (running on port 5800+display_number), you have to set rfbScreen->httpdDir to a directory containing vncviewer.jar and index.vnc (like the included "classes" directory). Hooks and IO functions ---------------------- There exist the following IO functions as members of rfbScreen: kbdAddEvent, kbdReleaseAllKeys, ptrAddEvent and setXCutText kbdAddEvent(Bool down,KeySym key,rfbClientPtr cl) is called when a key is pressed. kbdReleaseAllKeys(rfbClientPtr cl) is not called at all (maybe in the future). ptrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl) is called when the mouse moves or a button is pressed. setXCutText(char* str,int len,rfbClientPtr cl) is called when the selection changes. There is only one hook: newClientHook(rfbClientPtr cl) is called when a new client has connected. You can also override the following method: getCursorPtr(rfbClientPtr cl) This could be used to make an animated cursor (if you really want ...) Cursor handling --------------- The screen holds a pointer rfbCursorPtr cursor to the current cursor. Whenever you set it, remember that any dynamically created cursor (like return value from rfbMakeXCursor) is not free'd! The rfbCursor structure consists mainly of a mask and a source. The mask describes, which pixels are drawn for the cursor (a cursor needn't be rectangular). The source describes, which colour those pixels should have. The standard is an XCursor: a cursor with a foreground and a background colour (stored in backRed,backGreen,backBlue and the same for foreground in a range from 0-0xffff). Therefore, the arrays "mask" and "source" contain pixels as single bits stored in bytes in MSB order. The rows are padded, such that each row begins with a new byte (i.e. a 10x4 cursor's mask has 2x4 bytes, because 2 bytes are needed to hold 10 bits). It is however very easy to make a cursor like this: char* cur=" " " xx " " x " " "; char* mask="xxxx" "xxxx" "xxxx" "xxx "; rfbCursorPtr c=rfbMakeXCursor(4,4,cur,mask); You can even set "mask" to NULL in this call and LibVNCServer will calculate a mask for you (dynamically, so you have to free it yourself). There is also an array named "richSource" for colourful cursors. They have the same format as the frameBuffer (i.e. if the server is 32 bit, a 10x4 cursor has 4x10x4 bytes). History ------- LibVNCServer is based on Tridia VNC and OSXvnc, which in turn are based on the original code from ORL/AT&T. VNC fascinated me from t License ------- This program 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 program 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.dfdf For help with OSXvnc, please visit http://www.osxvnc.com/.