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