Home | History | Annotate | Download | only in libvncserver
      1 LibVNCServer: A library for easy implementation of a VNC server.
      2 Copyright (C) 2001-2003 Johannes E. Schindelin
      3 
      4 If you already used LibVNCServer, you probably want to read NEWS.
      5 
      6 What is it?
      7 -----------
      8 
      9 VNC is a set of programs using the RFB (Remote Frame Buffer) protocol. They
     10 are designed to "export" a frame buffer via net (if you don't know VNC, I
     11 suggest you read "Basics" below). It is already in wide use for
     12 administration, but it is not that easy to program a server yourself.
     13 
     14 This has been changed by LibVNCServer.
     15 
     16 There are two examples included:
     17  - example, a shared scribble sheet
     18  - pnmshow, a program to show PNMs (pictures) over the net.
     19 
     20 The examples are not too well documented, but easy straight forward and a
     21 good starting point.
     22 
     23 Try example: it outputs on which port it listens (default: 5900), so it is
     24 display 0. To view, call
     25 	vncviewer :0
     26 You should see a sheet with a gradient and "Hello World!" written on it. Try
     27 to paint something. Note that everytime you click, there is some bigger blot,
     28 whereas when you drag the mouse while clicked you draw a line. The size of the
     29 blot depends on the mouse button you click. Open a second vncviewer with
     30 the same parameters and watch it as you paint in the other window. This also
     31 works over internet. You just have to know either the name or the IP of your
     32 machine. Then it is
     33 	vncviewer machine.where.example.runs.com:0
     34 or similar for the remote client. Now you are ready to type something. Be sure
     35 that your mouse sits still, because everytime the mouse moves, the cursor is
     36 reset to the position of the pointer! If you are done with that demo, press
     37 the down or up arrows. If your viewer supports it, then the dimensions of the
     38 sheet change. Just press Escape in the viewer. Note that the server still
     39 runs, even if you closed both windows. When you reconnect now, everything you
     40 painted and wrote is still there. You can press "Page Up" for a blank page.
     41 
     42 The demo pnmshow is much simpler: you either provide a filename as argument
     43 or pipe a file through stdin. Note that the file has to be a raw pnm/ppm file,
     44 i.e. a truecolour graphics. Only the Escape key is implemented. This may be
     45 the best starting point if you want to learn how to use LibVNCServer. You
     46 are confronted with the fact that the bytes per pixel can only be 8, 16 or 32.
     47 
     48 Projects using it
     49 ----------------------------------------
     50 
     51 VNC for KDE
     52 http://www.tjansen.de/krfb
     53 
     54 GemsVNC
     55 http://www.elilabs.com/~rj/gemsvnc/
     56 
     57 VNC for Netware
     58 http://forge.novell.com/modules/xfmod/project/?vncnw
     59 
     60 RDesktop
     61 http://rdesktop.sourceforge.net
     62 
     63 Mail me, if your application is missing!
     64 
     65 How to use
     66 ----------
     67 
     68 To make a server, you just have to initialise a server structure using the
     69 function rfbDefaultScreenInit, like
     70   rfbScreenInfoPtr rfbScreen =
     71     rfbGetScreen(argc,argv,width,height,8,3,bpp);
     72 where byte per pixel should be 1, 2 or 4. If performance doesn't matter,
     73 you may try bpp=3 (internally one cannot use native data types in this
     74 case; if you want to use this, look at pnmshow24).
     75 
     76 
     77 You then can set hooks and io functions (see below) or other
     78 options (see below).
     79 
     80 And you allocate the frame buffer like this:
     81     rfbScreen->frameBuffer = (char*)malloc(width*height*bpp);
     82 
     83 After that, you initialize the server, like
     84   rfbInitServer(rfbScreen);
     85 
     86 You can use a blocking event loop, a background (pthread based) event loop,
     87 or implement your own using the rfbProcessEvents function.
     88 
     89 Making it interactive
     90 ---------------------
     91 
     92 Input is handled by IO functions (see below).
     93 
     94 Whenever you change something in the frame buffer, call rfbMarkRectAsModified.
     95 You should make sure that the cursor is not drawn before drawing yourself
     96 by calling rfbUndrawCursor. You can also draw the cursor using rfbDrawCursor,
     97 but it hardly seems necessary. For cursor details, see below.
     98 
     99 Utility functions
    100 -----------------
    101 
    102 Whenever you draw something, you have to call
    103  rfbMarkRectAsModified(screen,x1,y1,x2,y2).
    104 This tells LibVNCServer to send updates to all connected clients.
    105 
    106 Before you draw something, be sure to call
    107  rfbUndrawCursor(screen).
    108 This tells LibVNCServer to hide the cursor.
    109 Remark: There are vncviewers out there, which know a cursor encoding, so
    110 that network traffic is low, and also the cursor doesn't need to be
    111 drawn the cursor everytime an update is sent. LibVNCServer handles
    112 all the details. Just set the cursor and don't bother any more.
    113 
    114 To set the mouse coordinates (or emulate mouse clicks), call
    115   defaultPtrAddEvent(buttonMask,x,y,cl);
    116 IMPORTANT: do this at the end of your function, because this actually draws
    117 the cursor if no cursor encoding is active.
    118 
    119 What is the difference between rfbScreenInfoPtr and rfbClientPtr?
    120 -----------------------------------------------------------------
    121 
    122 The rfbScreenInfoPtr is a pointer to a rfbScreenInfo structure, which
    123 holds information about the server, like pixel format, io functions,
    124 frame buffer etc.
    125 
    126 The rfbClientPtr is a pointer to an rfbClientRec structure, which holds
    127 information about a client, like pixel format, socket of the
    128 connection, etc.
    129 
    130 A server can have several clients, but needn't have any. So, if you
    131 have a server and three clients are connected, you have one instance
    132 of a rfbScreenInfo and three instances of rfbClientRec's.
    133 
    134 The rfbClientRec structure holds a member
    135   rfbScreenInfoPtr screen
    136 which points to the server and a member
    137   rfbClientPtr next
    138 to the next client.
    139 
    140 The rfbScreenInfo structure holds a member
    141   rfbClientPtr rfbClientHead
    142 which points to the first client.
    143 
    144 So, to access the server from the client structure, you use client->screen.
    145 To access all clients from a server, get screen->rfbClientHead and
    146 iterate using client->next.
    147 
    148 If you change client settings, be sure to use the provided iterator
    149  rfbGetClientIterator(rfbScreen)
    150 with
    151  rfbClientIteratorNext(iterator)
    152 and
    153  rfbReleaseClientIterator
    154 to prevent thread clashes.
    155 
    156 Other options
    157 -------------
    158 
    159 These options have to be set between rfbGetScreen and rfbInitServer.
    160 
    161 If you already have a socket to talk to, just set rfbScreen->inetdSock
    162 (originally this is for inetd handling, but why not use it for your purpose?).
    163 
    164 To also start an HTTP server (running on port 5800+display_number), you have
    165 to set rfbScreen->httpdDir to a directory containing vncviewer.jar and
    166 index.vnc (like the included "webclients" directory).
    167 
    168 Hooks and IO functions
    169 ----------------------
    170 
    171 There exist the following IO functions as members of rfbScreen:
    172 kbdAddEvent, kbdReleaseAllKeys, ptrAddEvent and setXCutText
    173 
    174 kbdAddEvent(rfbBool down,rfbKeySym key,rfbClientPtr cl)
    175   is called when a key is pressed.
    176 kbdReleaseAllKeys(rfbClientPtr cl)
    177   is not called at all (maybe in the future).
    178 ptrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl)
    179   is called when the mouse moves or a button is pressed.
    180   WARNING: if you want to have proper cursor handling, call
    181 	defaultPtrAddEvent(buttonMask,x,y,cl)
    182   in your own function. This sets the coordinates of the cursor.
    183 setXCutText(char* str,int len,rfbClientPtr cl)
    184   is called when the selection changes.
    185 
    186 There are only two hooks:
    187 newClientHook(rfbClientPtr cl)
    188   is called when a new client has connected.
    189 displayHook
    190   is called just before a frame buffer update is sent.
    191 
    192 You can also override the following methods:
    193 getCursorPtr(rfbClientPtr cl)
    194   This could be used to make an animated cursor (if you really want ...)
    195 setTranslateFunction(rfbClientPtr cl)
    196   If you insist on colour maps or something more obscure, you have to
    197   implement this. Default is a trueColour mapping.
    198 
    199 Cursor handling
    200 ---------------
    201 
    202 The screen holds a pointer
    203  rfbCursorPtr cursor
    204 to the current cursor. Whenever you set it, remember that any dynamically
    205 created cursor (like return value from rfbMakeXCursor) is not free'd!
    206 
    207 The rfbCursor structure consists mainly of a mask and a source. The mask
    208 describes, which pixels are drawn for the cursor (a cursor needn't be
    209 rectangular). The source describes, which colour those pixels should have.
    210 
    211 The standard is an XCursor: a cursor with a foreground and a background
    212 colour (stored in backRed,backGreen,backBlue and the same for foreground
    213 in a range from 0-0xffff). Therefore, the arrays "mask" and "source"
    214 contain pixels as single bits stored in bytes in MSB order. The rows are
    215 padded, such that each row begins with a new byte (i.e. a 10x4
    216 cursor's mask has 2x4 bytes, because 2 bytes are needed to hold 10 bits).
    217 
    218 It is however very easy to make a cursor like this:
    219 
    220 char* cur="    "
    221           " xx "
    222 	  " x  "
    223 	  "    ";
    224 char* mask="xxxx"
    225            "xxxx"
    226 	   "xxxx"
    227 	   "xxx ";
    228 rfbCursorPtr c=rfbMakeXCursor(4,4,cur,mask);
    229 
    230 You can even set "mask" to NULL in this call and LibVNCServer will calculate
    231 a mask for you (dynamically, so you have to free it yourself).
    232 
    233 There is also an array named "richSource" for colourful cursors. They have
    234 the same format as the frameBuffer (i.e. if the server is 32 bit,
    235 a 10x4 cursor has 4x10x4 bytes).
    236 
    237 History
    238 -------
    239 
    240 LibVNCServer is based on Tridia VNC and OSXvnc, which in turn are based on
    241 the original code from ORL/AT&T.
    242 
    243 When I began hacking with computers, my first interest was speed. So, when I
    244 got around assembler, I programmed the floppy to do much of the work, because
    245 it's clock rate was higher than that of my C64. This was my first experience
    246 with client/server techniques.
    247 
    248 When I came around Xwindows (much later), I was at once intrigued by the
    249 elegance of such connectedness between the different computers. I used it
    250 a lot - not the least priority lay on games. However, when I tried it over
    251 modem from home, it was no longer that much fun.
    252 
    253 When I started working with ASP (Application Service Provider) programs, I
    254 tumbled across Tarantella and Citrix. Being a security fanatic, the idea of
    255 running a server on windows didn't appeal to me, so Citrix went down the
    256 basket. However, Tarantella has it's own problems (security as well as the
    257 high price). But at the same time somebody told me about this "great little
    258 administrator's tool" named VNC. Being used to windows programs' sizes, the
    259 surprise was reciprocal inverse to the size of VNC!
    260 
    261 At the same time, the program "rdesktop" (a native Linux client for the
    262 Terminal Services of Windows servers) came to my attention. There where even
    263 works under way to make a protocol converter "rdp2vnc" out of this. However,
    264 my primary goal was a slow connection and rdp2vnc could only speak RRE
    265 encoding, which is not that funny with just 5kB/s. Tim Edmonds, the original
    266 author of rdp2vnc, suggested that I adapt it to Hextile Encoding, which is
    267 better. I first tried that, but had no success at all (crunchy pictures).
    268 
    269 Also, I liked the idea of an HTTP server included and possibly other
    270 encodings like the Tight Encodings from Const Kaplinsky. So I started looking
    271 for libraries implementing a VNC server where I could steal what I can't make.
    272 I found some programs based on the demo server from AT&T, which was also the
    273 basis for rdp2vnc (can only speak Raw and RRE encoding). There were some
    274 rumors that GGI has a VNC backend, but I didn't find any code, so probably
    275 there wasn't a working version anyway.
    276 
    277 All of a sudden, everything changed: I read on freshmeat that "OSXvnc" was
    278 released. I looked at the code and it was not much of a problem to work out
    279 a simple server - using every functionality there is in Xvnc. It became clear
    280 to me that I *had* to build a library out of it, so everybody can use it.
    281 Every change, every new feature can propagate to every user of it.
    282 
    283 It also makes everything easier:
    284  You don't care about the cursor, once set (or use the standard cursor).
    285 You don't care about those sockets. You don't care about encodings.
    286 You just change your frame buffer and inform the library about it. Every once
    287 in a while you call rfbProcessEvents and that's it.
    288 
    289 Basics
    290 ------
    291 
    292 VNC (Virtual network computing) works like this: You set up a server and can
    293 connect to it via vncviewers. The communication uses a protocol named RFB
    294 (Remote Frame Buffer). If the server supports HTTP, you can also connect
    295 using a java enabled browser. In this case, the server sends back a
    296 vncviewer applet with the correct settings.
    297 
    298 There exist several encodings for VNC, which are used to compress the regions
    299 which have changed before they are sent to the client. A client need not be
    300 able to understand every encoding, but at least Raw encoding. Which encoding
    301 it understands is negotiated by the RFB protocol.
    302 
    303 The following encodings are known to me:
    304 Raw, RRE, CoRRE, Hextile, CopyRect from the original AT&T code and
    305 Tight, ZLib, LastRect, XCursor, RichCursor from Const Kaplinsky et al.
    306 
    307 If you are using a modem, you want to try the "new" encodings. Especially
    308 with my 56k modem I like ZLib or Tight with Quality 0. In my tests, it even
    309 beats Tarantella.
    310 
    311 There is the possibility to set a password, which is also negotiated by the
    312 RFB protocol, but IT IS NOT SECURE. Anybody sniffing your net can get the
    313 password. You really should tunnel through SSH.
    314 
    315 Windows or: why do you do that to me?
    316 --------------------------------------------
    317 
    318 If you love products from Redmod, you better skip this paragraph.
    319 I am always amazed how people react whenever Microsoft(tm) puts in some
    320 features into their products which were around for a long time. Especially
    321 reporters seem to not know dick about what they are reporting about! But
    322 what is everytime annoying again, is that they don't do it right. Every
    323 concept has it's new name (remember what enumerators used to be until
    324 Mickeysoft(tm) claimed that enumerators are what we thought were iterators.
    325 Yeah right, enumerators are also containers. They are not separated. Muddy.)
    326 
    327 There are three packages you want to get hold of: zlib, jpeg and pthreads.
    328 The latter is not strictly necessary, but when you put something like this
    329 into your source:
    330 
    331 #define MUTEX(s)
    332 	struct {
    333 		int something;
    334 		MUTEX(latex);
    335 	}
    336 
    337 Microsoft's C++ compiler doesn't do it. It complains that this is an error.
    338 This, however, is how I implemented mutexes in case you don't need pthreads,
    339 and so don't need the mutex.
    340 
    341 You can find the packages at
    342 http://www.gimp.org/win32/extralibs-dev-20001007.zip
    343 
    344 Thanks go to all the GIMP team!
    345 
    346 What are those other targets in the Makefile?
    347 ---------------------------------------------
    348 
    349 OSXvnc-server is the original OSXvnc adapted to use the library, which was in
    350 turn adapted from OSXvnc. As you easily can see, the OSX dependend part is
    351 minimal.
    352 
    353 storepasswd is the original program to save a vnc style password in a file.
    354 Unfortunately, authentication as every vncviewer speaks it means the server
    355 has to know the plain password. You really should tunnel via ssh or use
    356 your own PasswordCheck to build a PIN/TAN system.
    357 
    358 sratest is a test unit. Run it to assert correct behaviour of sraRegion. I
    359 wrote this to test my iterator implementation.
    360 
    361 blooptest is a test of pthreads. It is just the example, but with a background
    362 loop to hunt down thread lockups.
    363 
    364 pnmshow24 is like pnmshow, but it uses 3 bytes/pixel internally, which is not
    365 as efficient as 4 bytes/pixel for translation, because there is no native data
    366 type of that size, so you have to memcpy pixels and be real cautious with
    367 endianness. Anyway, it works.
    368 
    369 fontsel is a test for rfbSelectBox and rfbLoadConsoleFont. If you have Linux
    370 console fonts, you can browse them via VNC. Directory browsing not implemented
    371 yet :-(
    372 
    373 Why I don't feel bad about GPL
    374 ------------------------------
    375 
    376 At the beginning of this projects I would have liked to make it a BSD
    377 license. However, it is based on plenty of GPL'ed code, so it has to be
    378 a GPL. I hear BeeGee complaining: "but that's invasive, every derivative
    379 work, even just linking, makes my software GPL!"
    380 
    381 Yeah. That's right. It is because there are nasty jarheads out there who
    382 would take anybody's work and claim it their own, selling it for much too
    383 much money, stealing freedom and innovation from others, saying they were
    384 the maintainers of innovation, lying, making money with that.
    385 
    386 The people at AT&T worked really well to produce something as clean and lean
    387 as VNC. The managers decided that for their fame, they would release the
    388 program for free. But not only that! They realized that by releasing also
    389 the code for free, VNC would become an evolving little child, conquering
    390 new worlds, making it's parents very proud. As well they can be! To protect
    391 this innovation, they decided to make it GPL, not BSD. The principal
    392 difference is: You can make closed source programs deriving from BSD, not
    393 from GPL. You have to give proper credit with both.
    394 
    395 Now, why not BSD? Well, imagine your child being some famous actor. Along
    396 comes a manager who exploits your child exclusively, that is: nobody else
    397 can profit from the child, it itself included. Got it?
    398 
    399 What reason do you have now to use this library commercially?
    400 
    401 Several: You don't have to give away your product. Then you have effectively
    402 circumvented the GPL, because you have the benefits of other's work and you
    403 don't give back anything and you will be in hell for that. In fact, this
    404 library, as my other projects, is a payback for all the free software I can
    405 use (and sometimes, make better). For example, just now, I am using XEmacs
    406 on top of XFree86, all running under Linux.
    407 
    408 Better: Use a concept like MySQL. This is free software, however, they make
    409 money with it. If you want something implemented, you have the choice:
    410 Ask them to do it (and pay a fair price), or do it yourself, normally giving
    411 back your enhancements to the free world of computing.
    412 
    413 Learn from it: If you like the style this is written, learn how to imitate
    414 it. If you don't like the style, learn how to avoid those things you don't
    415 like. I learnt so much, just from looking at code like Linux, XEmacs,
    416 LilyPond, STL, etc.
    417 
    418 License
    419 -------
    420 
    421 This program is free software; you can redistribute it and/or
    422 modify it under the terms of the GNU General Public License
    423 as published by the Free Software Foundation; either version 2
    424 of the License, or (at your option) any later version.
    425 
    426 This program is distributed in the hope that it will be useful,
    427 but WITHOUT ANY WARRANTY; without even the implied warranty of
    428 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    429 GNU General Public License for more details.
    430 
    431 You should have received a copy of the GNU General Public License
    432 along with this program; if not, write to the Free Software
    433 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.dfdf
    434 
    435 Contact
    436 -------
    437 
    438 To contact me, mail me: Johannes dot Schindelin at gmx dot de
    439 
    440