
VNC server
==========

This is a VNC server for RISC OS. Some things aren't quite working yet.


In use
------

Modify the obey file 'start' to use the port no. and password you want to use.
Notice that the password can be at most 8 chars.

Select a suitable screen mode (see Optimising).

If you plan to use a client with a 2 button mouse, you may want to enable the
line 'vncserv_swap_adjust_menu 1' in the 'start' obey file.

Double click on 'start' and the server will load and start listening for an
incoming connection; the server hardly uses any CPU when no client is
connected, so you may have the server running constantly.

Set up the VNC client/viewer to use the selected port no. and password and
connect to the machine running the server.

If you run into problems, some debug output is available via SysLog. Make sure
SysLog is loaded and set the vncserv_debug system variable to 1. You can also
get a status report from the server via *vncserv_status.


Configuration
-------------

The following *commands can be used to configure the operation of the server:

*vncserv_mouse_kbd

  For security the server starts with the mouse and keyboard disabled. This
  command is used to enable mouse/keyboard handling.

*vncserv_swap_adjust_menu 0 | 1

  Enable or disable the swapping of the 'Menu' and 'Adjust' mouse buttons.

  Default value: 0

*vncserv_dont_nudge_mouse

  Disable the mouse nudging behaviour when the server detects that callbacks are
  blocked (see "Missing/bugs/future improvements")

*vncserv_prefer_xcursor -1 | 0 | 1

  Control which type of cursor encoding (Cursor or XCursor) is preferred by the
  server:

  -1 -> always use Cursor encoding if available
  0 -> auto-select encoding (prefers XCursor if current pointer image has <3
       colours)
  1 -> always use XCursor encoding if available

  Default value: 0

  It's recommended to leave this setting at the default unless you have trouble
  with the cursor display with some clients/screen modes.

  E.g. !Avalanche 0.12 will render an XCursor-encoded cursor as black for
  connections which are at <= 8bpp, so you must use either connect at a higher
  BPP or alter the client or server settings to force Cursor encoding (e.g.
  '*vncserv_prefer_xcursor -1')

  However Cursor also has its own drawbacks, e.g. if the server is in a 256 grey
  mode and the connection is at 8bpp or less then the server will only be able
  to pick the cursor colours out of the greyscale palette which is being used
  for the desktop image, so a Cursor-encoded cursor will appear in greyscale.

*vncserv_enable_clipboard 0 | 1

  Enable/disable clipboard integration. This feature requires RISC OS 4 or
  later.

  Default value: 0

*vncserv_zlib_level -1 ... +9

  Enable/disable ZLib and ZRLE encodings and set the stream compression level.

  -1 -> Disable both ZLib and ZRLE encodings
  0 -> Enable ZRLE with no compression
  1 ... 9 -> Enable both ZLib and ZRLE, with the given compression level

  Note that even without compression being enabled, the ZLib module is required
  in order for ZLib/ZRLE to operate.

  Compression levels of greater than zero require significant CPU time. If you
  need to use compression, it's not recommended to go above level 1.

  Note that ZRLE with no compression generally results in lower bandwidth and
  better performance than Hextile encoding.

  If both ZLib and ZRLE are enabled then the server will prefer to use ZRLE over
  ZLib.

  Default value: -1

*vncserv_enable_filter 0 | 1

  Enable/disable use of the Filter Manager to detect screen updates when in the
  Wimp. This results in lower CPU usage by the server and more responsive
  screen updates. However note the current implementation does not catch all
  types of screen redraw events (most significantly, mouse drag operations).
  This feature requires RISC OS 4 or later.

  Default value: 0

*vncserv_stretch_keys 0 | 1

  Stretch the duration of certain keypress events so that the key debounce code
  built into the kernel sees the event as a valid key press. When running the
  server on an OS version prior to RISC OS 5, and when connecting from a client
  that sends rapid down-up events for certain keys (e.g. !Avalanche), this
  option is required in order for those keys to operate correctly (function
  keys, Return, Control, etc.)

  Default value: 1


Optimising
----------

When running on a modern RISC OS machine and when accessed over a fast LAN the
server should have acceptable performance. However if you are using it with
older machines or over slow networks you might want to try the following advice.

The backdrop should be monochrome. Use !CloseUp to check that the backdrop
isn't a dithered pattern. Disabling textured windows is also a good idea, so is
using simple toolsprites.

Using a smaller screen mode and/or lower colour depth helps.

Antialiased text does not compress well with VNC - try disabling antialising
and use the system font in the Wimp.

Make sure the client doesn't connect at a higher colour depth than the server
is using. Connecting at 8bpp will reduce network bandwidth and CPU load on the
server.

Using ZLib compression (vncserv_zlib_level greater than zero) has a very high
CPU cost and (when using a fast LAN) this CPU cost will typically be greater
than the time it would otherwise take to send the uncompressed data. However
when accessing the server over the internet, using ZLib might be worth it.

Enabling the Filter Manager (vncserv_enable_filter) will generally result in a
more responsive experience; however note that the current implementation will
not catch all screen redraw events (most significantly, mouse drag operations).


Supported encodings
-------------------

The server supports the following framebuffer update encodings (most-preferred
to least-preferred - currently the server ignores the preference ordering
specified by the client):

* ZRLE
* ZLib
* Hextile
* Raw

The server also understands the following pseudo-encodings:

* DesktopSize
* Cursor
* XCursor


Missing/bugs/future improvements
--------------------------------

Sometimes dragging a window freezes the network and locks the mouse buttons;
this happens if no callbacks are generated whilst dragging - why this is so for
some windows and not for others is not known. I've tried forcing a callback to
happen, but that seemed a little unstable. There now is a watchdog which nudges
the mouse if no callbacks have happened for about 1/4 second; this seems to
unfreeze the network. The watchdog can be disabled using
*vncserv_dont_nudge_mouse.

The server does not correctly cope with the case where both the client and
server are both using paletted modes, but the client requests a lower BPP than
the server. When this happens the displayed colours will be incorrect.

The pointer image is not sent when the client connects - you must click
somewhere to cause the image to change in order for it to appear.

Only basic VNC security is supported.

Only the basic VNC clipboard protocol is supported, which means that clipboard
content is limited to ISO 8859-1 text (a subset of the RISC OS Latin1 alphabet).

The Screen Sharing app on macOS typically produces a garbled display if the ZRLE / ZLib protocols are used. For now it's recommended to disable them (*vncserv_zlib_level -1) when using that client.


License
-------

This program is released under the GPL version 2. See the License file for
details.


Requirements
------------

Running the server requires RISC OS 3.5 or later.

Clipboard or Filter Manager support requires RISC OS 4 or later.

Using the ZLib or ZRLE encodings requires the ZLib module.

If the server is using a non-Latin1 system alphabet, RISC OS 5 or a suitable
Service_International 8 implementation is required to make sure that keyboard
input and clipboard text is correctly translated to and from the character
encodings used by the VNC protocol.


Recompilation
-------------

To compile you need OSLib and GCC.

* http://ro-oslib.sourceforge.net/
* http://www.riscos.info/index.php/GCC


Copyright/Authors
-----------------

The original version of the server was written by Henrik Bjerregaard Pedersen,
<henrik@login.dknet.dk>.

It has since been expanded and improved upon by:

* Crispian Daniels <crispian@beeb.net>
* David Llewellyn-Jones <david@flypig.co.uk> http://www.flypig.co.uk/
* Jeffrey Lee <me@phlamethrower.co.uk> http://www.phlamethrower.co.uk/


History
-------

0.01 2002-01-13 [henrik]
* First version

0.02 2002-01-17 [henrik]
* Fixed 100000 bugs

0.03 2002-01-18 [henrik]
* Some screen-scanning optimization
* Improved changed-rectangle detection
* Now keeps track of which keys are pressed

0.04 2002-01-19 [henrik]
* Split main.c into frontend.c and server.c
* Server quits and restarts on network error
* Better handling of keys

0.05 2002-01-21 [henrik]
* Fixed problem with F10, F11, F12

0.06 2002-01-27 [henrik]
* Attempt to fix the 'freezing when dragging window' problem

0.07 2006-01-13 [crispian]
* Altered server_poll() in c.server to continue listening for connections after
the connection is first made, to fix an inability to reconnect after the first
connection is made
* Modified poll_sending() in c.server to treat EAGAIN as non-fatal, to fix
frequent fatal errors
* Changed c.vncserv to prevent the accumulation of multiple (overlapping in
this case) area updates in the send buffer. This involved a data marker in c.
server. This fixed a case of the send buffer overflowing when the display
changes rapidly.
* io_keypress() now inserts the appropriate control characters into the
keyboard buffer which are required for Ctrl-X, etc. to work.

0.08 2006-01-14 [david]
* First 32bit compatible release

0.09 2006-08-23 [jeffrey]
* Removed dependency on NetLib, as the library no longer seems to be available.
All networking is now done via OSLib.
* Wrote a GCC makefile that can be used to build either the module or absolute
versions of the server (with minor modifications to the makefile)
* Changed server.c, vncserv.c, vncserv.h to add a checkscreenmode() call to the
vncservio struct. This is used to check whether the screen mode has been
changed, and if so the server will terminate itself. (You should be able to
reconnect straight away). Note that this vncservio change may be unnecessary,
as the same check is now also performed in server_poll()
* Tweaked the screenmode change detection so that if you change to an identical
mode, the server will keep running. You can now hit F12, type some commands,
and return to the desktop without the server barfing. It also supports hardware
scrolling, so you'll be able to properly see what you type.
* Added support for the DesktopSize pseudo-encoding. With the right VNC client
(e.g. !Avalanche), you will be able to change to most, if not all, screen modes
without having to reconnect.

0.10 2014-08-28 [jeffrey]
* Not sure what (if anything) changed for this release. Sorry!
* May have featured prototype support for the Cursor pesudo-encoding

0.11 2014-11-27 [jeffrey]
* Recompiled using GCC 4.1.2 release 2 + OSLib 7.00 in order to produce an
ARMv7 compatible version. Some 32bit-unsafe assembler has also been fixed.

0.12 2014-12-07 [jeffrey]
* Rewrote this documentation to get rid of all the different readmes each
author had added
* Replaced some magic numbers in the source with symbolic constants + other
bits of code tidying
* Rewrote pixtrans code from scratch. The server should now cope with any RISC
OS screen mode (was previously limited to 4bpp, 8bpp & 16bpp; should now cope
with all modes including the new RISC OS 5.21 modes)
* Added support for 32bpp hextile encoding (previously only supported clients
which connected at 8bpp or 16bpp, causing a black screen if the client
requested 32bpp).
* The server will now also explicitly set the palette the client should use,
instead of assuming a certain fixed palette is in use.
* Fixed and improved Cursor pseudo-encoding
* Added support for XCursor pseudo-encoding; by default Cursor encoding will be
preferred, but *vncserv_perfer_xcursor can be used to alter the behaviour if
required.
* Added *vncserv_status command to output status information about the server
and the client
* Tidied up checkscreenmode() and DesktopSize handling
* Added support for debug output via the SysLog module; enable by setting the
vncserv_debug system variable to 1. Make sure SysLog is loaded as well!
* Removed support for building as an application - mostly redundant now that
debug output is available from the module version
* Added scroll wheel support, using Wimp scroll messages/WimpScroll module

0.13 2015-11-22 [jeffrey]
* Fixed connection always closing after 1000 seconds (about 16 minutes) - now
waits for 1000s of inactivity from the client
* Fixed to use correct eigen values for the current screen mode when
translating mouse position - previously assumed EX1 EY1 mode was in use
* Fix mouse nudge code to read current mouse position from OS instead of using
last position received from client - may fix cursor jumping in some situations
(e.g. on first connect)
* Fix old socket not being closed correctly when a new client connects
* Fix server to disconnect if an unexpected message type is received
(previously, would effective stop the server without actually disconnecting)

0.14 2016-04-16 [jeffrey]
* Fixed a bug where pointer update messages being generated under IRQ were
being written into the send buffer while other data was being prepared in the
foreground, causing corrupt packets to be sent over the network. Pointer
updates are now sent from the foreground, along with all other messages.
* Fixed a bug where if you disconnect while the server is sending data, the
server may not send any new data if you reconnect
* Fixed 32bpp hextile encoding using the wrong threshold when deciding if
encoding a tile as hextile is worth it or not in terms of network bandwidth
* Fixed SO_REUSEADDR not being set correctly on the listen socket
* Added some profiling calls to the source to allow server performance to be
measured (can be enabled in profiling.h). Uses a HAL timer and the debug out
(SysLog).
* Rewrote transmit buffer handling to use a circular buffer instead of
shuffling the data around all the time.
* The internet event is now used to monitor the transmit buffer of the socket,
allowing for much greater network throughput than before
* Server update logic has been moved from a 50Hz tick to 100Hz to try and get
further responsiveness gains
* Optimised pixel translation code for a couple of common cases
* Added clipboard/copy-and-paste support. This uses the Wimp clipboard
protocol, and so only works when in the desktop. Note that the VNC protocol
implemented only supports plain Latin1 text, and vncserver does not currently
perform any character translation. If necessary, clipboard support can be
disabled via '*vncserv_enable_clipboard 0'
* Some misc bits of source tidying

0.15 2016-04-17 [jeffrey]
* Fixed vncserv_start to first stop the server if it is currently running
* Fixed frontend_start and server_start return codes not being checked
* Fixed circular buffer not being reset correctly when being released/resized

0.16 2016-07-23 [jeffrey]
* Massive cleanup and refactor of the code base in order to move all state out
of static variables and into structures, where initialisation/shutdown can be
more easily tracked
* Big refactor of the core state machine in order to allow framebuffer updates
and clipboard text to be sent asynchronously. This has allowed the size of the
transmit buffer to be reduced to a sensible level (~160k) instead of being
several megabytes in size. CPU usage by the server should now also be
friendlier (no big stalls due to the server blocking while it prepares large
updates).
* Reduced memory consumption further by making different pieces of code share
one global temporary data buffer instead of each using their own
* Added support for ZLib and ZRLE encodings
* Allow server to receive multiple packets per 100Hz tick; improves operation
with clients which send mouse updates at high frequencies, and generally
results in greater responsiveness
* Added support for using the Filter Manager to track screen updates
* Track multiple dirty rectangles instead of just one - e.g. avoids sending one
large rectangle covering the screen if something in the top-left changes at the
same time as something in the bottom-right
* Fixed operation when the client connects at < 8bpp. Note however that if the
server is at <= 8bpp and the client is at a lower depth than the server then
this will still have issues.
* Added key stretching code to combat kernel key debounce
* Added support for many more VNC key codes (e.g. Home, End, and the keypad)
* Fixed builtin Ctrl-modification of keypresses ignoring the right Ctrl key
* Improved Ctrl-modification of most keys to send them through KeyV instead of
inserting bytes into the keyboard buffer; this fixes e.g. Shift-Ctrl-C / Shift-
Ctrl-V in StrongED being detected as Ctrl-C / Ctrl-V
* Improved cursor handling so that vncserv_prefer_xcursor 0 will now auto-
select between XCursor and Cursor depending on the current pointer image
(XCursor requires less network bandwidth and has better colour reproduction,
but only supports two colours in the pointer image).
* Manually clamp the pointer to within the current pointer bounding box -
previously dragging scrollbars was very difficult, because if the mouse
wandered outside the box the OS would ignore the input instead of clamping it
itself.
* The makefile now uses automatic dependency generation instead of hardcoded
dependencies
* Fixed some VNC protocol state machine violations where events (cursor &
DesktopSize pseudo-encodings) could be sent at a time when the client hadn't
requested a framebuffer update
* Fixed an issue where received clipboard text was sometimes being discarded if
another program owned the clipboard
* Improved mouse nudging/callback unblocking logic to also release the Shift
keys - fixes issue where using Shift-Ctrl to pause screen scrolling would leave
you stuck because the main server update callback would stop running
* Probably some other stuff that I've forgotten about!

0.17 2017-02-04 [jeffrey]
* Fixed handling of character codes >= 128 when inserting into keyboard buffer
* All keyboard input received from the client will now be translated to the
current RISC OS alphabet (requires Service_International 8 / RISC OS 5). This
enables the full range of UTF-8 characters to be used if using a Unicode-
capable client and 'UTF8' alphabet on the server.
* Improved clipboard text handling to also perform translation to and from the
current RISC OS alphabet.

0.18 2017-08-28 [jeffrey]
* Fixed handling of RAM transmit protocol when reading the RISC OS clipboard; this fixes some problems with StrongED misbehaving when it owns the clipboard. However, there are also some bugs in StrongED itself (version 4.69f9) which will cause menus to spontaneously close when StrongED owns the clipboard, so disabling clipboard support in the VNC server (*vncserv_enable_clipboard 0) might be wise if a new StrongED version isn't available yet.
* Fixed screen handling to cope with modes where scanlines aren't tightly packed in memory

0.19 2018-01-19 [jeffrey]
* Fixed special keys not working correctly if the computer has no keyboard connected (by ensuring the kernel's keyboard driver is configured/enabled)

0.20 2019-08-31 [jeffrey]
* Fixed dirty rectangles sometimes being lost, causing some screen updates to not be sent to the client
