VNCDOTOOL(1)

πŸ“¦
version 1.3.0 Β· 3 versions
, in ubuntu stonking

πŸ’– VNCDOTOOL(1) πŸ’–

okay bestie, welcome to vncdotool β€” the manual page, but make it cute. this is the full VNCDoTool documentation and we're doing it properly, no skimming, no cutting corners. every flag, every example, every weird roff artifact β€” all of it stays. let's go ✨


🌸 NAME 🌸

vncdotool β€” VNCDoTool Documentation, periodt.


πŸ¦‹ INTRODUCTION πŸ¦‹

target: https://pypi.python.org/pypi/vncdotool

alt: Python Versions

there's a lil badge situation at the top of the docs, and we're reproducing it fr:

πŸ‘‘ VNCDOTOOL πŸ‘‘

vncdotool is a command line VNC client. it's lowkey iconic for automating interactions with virtual machines or hardware devices that are otherwise genuinely a nightmare to control.

it's under active development and seems to be working, BUT β€” and she means this β€” please report any problems you have. πŸ™ˆ

πŸ’… Quick Start

to use vncdotool you're gonna need a VNC server. most virtualization products include one, or you can use RealVNC, TightVNC, or clone your Desktop using x11vnc. pick your fighter.

once you have a server running you can install vncdotool from pypi:

pip install vncdotool

and then send a message to the vncserver with:

vncdo -s vncserver type "hello world"

the vncserver argument needs to be in the format address[:display|::port]. for example:

# connect to 192.168.1.1 on default port 5900
vncdo -s 192.168.1.1 type "hello world"

# connect to localhost on display :3 (port 5903)
vncdo -s localhost:3 type "hello world"

# connect to myvncserver.com on port 5902 (two colons needed)
vncdo -s myvncserver.com::5902 type "hello world"

# connect via IPv6 to localhost on display :3 (port 5903)
vncdo -s '[::1]:3' type "hello IPv6"
#         ^   ^ mind those square brackets around the IPv6 address

you can also take a screen capture with:

vncdo -s vncserver capture screen.png

more documentation can be found on Read the Docs at http://vncdotool.readthedocs.org. πŸŽ€

🫢 Feedback

if you need help getting VNCDoTool working, try the community at Stackoverflow: https://stackoverflow.com/questions/ask?tags=vncdotool.

patches and ideas for improvements are welcome and appreciated, via GitHub issues at http://github.com/sibson/vncdotool. and bestie, if you're reporting a bug or issue, please include the version of both vncdotool and the VNC server you are using it with. that's the difference between a fix and a mystery.

⭐ Acknowledgements

thanks to Chris Liechti, techtonik and Todd Whiteman for developing the RFB and DES implementations used by vncdotool. also, to the TigerVNC project for creating a community focus RFB specification document β€” http://sourceforge.net/apps/mediawiki/tigervnc/index.php?title=Main_Page. legends only. πŸ‘‘


🌈 INSTALLATION 🌈

vncdotool is available on PyPI at https://pypi.python.org/pypi, so in most cases you should be able to simply run:

pip install vncdotool

vncdotool relies on a number of libraries β€” the two major ones are Pillow (https://python-pillow.org/), the Python Imaging Library, and Twisted (https://twistedmatrix.com/), an asynchronous networking library. while vncdotool should work with any recent version of these libraries, sometimes things break. it's giving ✨fragile✨ but we move.

if you are having issues getting things to work you can try using a stable set of libraries, and if you aren't already using it β€” and you should be β€” use a virtualenv (https://virtualenv.pypa.io/):

pip install virtualenv
virtualenv venv-vncdotool
# XXX requirements.txt from vncdotool source tree
pip install -r requirements.txt
pip install -e .

πŸ“ Windows

if you are not familiar with Python, the most reliable way to install vncdotool is to use binary packages.

  1. Download Python, current 64-bit Windows Version, from Official Python (https://python.org/downloads/) website (https://www.python.org/downloads/)
  2. Start the installation. On the first screen of the installer...
    • Check the box for "Add Python to PATH",
    • Any other check boxes can be left checked or unchecked per their default
    • Click "Customize installation"
    • On the Optional Features install page, no changes are needed
    • On the Advanced Options page...
      • Make sure the boxes for "Install for all users" and "Add Python to environment variables" are checked
      • Uncheck "Precompile standard library" unless needed for other projects
      • Any other check boxes can be left checked or unchecked per their default
    • Click "Install" at the bottom
  3. Open an elevated Windows PowerShell console:
    • Type "PowerShell" (without quotes) in the search field of the Windows taskbar
    • Click "Run as administrator" in the right pane above the search field
    • Type or paste each of the following lines below, pressing Enter after each line and waiting for each line to process (change β€œPython39” to different version as applicable):
[Environment]::SetEnvironmentVariable("Path", "$env:Path;C:\Program Files\Python39\;C:\Program Files\Python39\Scripts\", "User")
python -m pip install --upgrade pip
pip install vncdotool
  1. At a Powershell prompt:
vncdo.exe --server som.eip.add.res type "Hello World"
  1. If Hello World shows up on the remote machine that has a VNC server running then its time to celebrate. πŸŽ‰ otherwise, first check you can connect from your local machine to the remote using a normal GUI VNC Client. once you get the normal GUI client working try vncdotool again, and if you still have problems try the community at Stackoverflow: https://stackoverflow.com/questions/ask?tags=vncdotool.

πŸ’œ USAGE πŸ’œ

🌸 Basic Usage

once installed you can use the vncdotool command to send key-presses. alphanumerics are straightforward β€” just specify the character. for other keys, longer names are used:

> vncdo key a
> vncdo key 5
> vncdo key .
> vncdo key enter
> vncdo key shift-a
> vncdo key ctrl-C
> vncdo key ctrl-alt-del

to type longer strings when entering data or commands you can use the type c command, which does not support special characters:

> vncdo type "hello world"

you can control the mouse pointer with move and click commands. NOTE, you should almost always issue a move before a click, as in:

> vncdo move 100 100 click 1

the following would seem to be equivalent but would actually click at (0, 0). this occurs due to how click events are encoded by VNC, meaning you need to initialise the position of the mouse:

> vncdo move 100 100
> vncdo click 1

if you have the Python Imaging Library (Pillow http://www.pythonware.com/products/pil) installed you can also make screen captures of the session:

> vncdo capture screenshot.png

with Pillow (http://www.pythonware.com/products/pil) installed, you can wait for the screen to match a known image:

> vncdo expect somescreen.png 0

putting it all together you can specify multiple actions on a single command line. you could automate a login with the following:

> vncdo type username key enter expect password_prompt.png
> vncdo type password move 100 150 click 1 expect welcome_screen.png

sometimes you only care about a portion of the screen, in which case you can use rcapture and rexpect. for instance, if your login window appears at x=100, y=200 and is 400 pixels wide by 250 high you could do:

> vncdo rcapture region.png 100 200 400 250
> vncdo rexpect region.png 100 200 0

🧚 Running Scripts

for more complex automation you can read commands from stdin or a file. the file format is simply a collection of actions:

> echo "type hello" | vncdo -

or if you had a file called login.vdo with the following content:

# select the name text box, enter your name and submit
move 100 100 click 1 type "my name" key tab key enter

# grab the result
capture screenshot.png

you could run it with the following command:

> vncdo login.vdo

πŸŽ€ Creating Scripts

while you can create scripts by hand it can often be a time consuming process. to make the process easier vncdotool provides a log mode that allows a user to record a VNC session to a script which is playable by vncdo. vnclog acts as a man-in-the-middle to record the VNC commands you issue with a client. so you will have your vnclog connect to your server and your viewer connect to vnclog:

vncviewer ---> vnclog ---> vncserver

for best results be sure to set your vncviewer client to use the RAW encoding. others encoding may work but are not fully supported at this time.

the quickest way to get started is to run:

> vnclog --viewer vncviewer keylog.vdo

for more control you can launch the viewer separately but be sure to connect to the correct ports:

> vnclog keylog.vdo
> vncviewer localhost:2  # do something and then exit viewer
> vncdo keylog.vdo

by running with --forever vnclog will create a new file for every client connection and record each clients activity. this can be useful for quickly recording a number of testcases.:

> vnclog --forever --listen 6000 /tmp
> vncviewer localhost::6000
# do some stuff then exit and start new session
> vncviewer localhost::6000
# do some other stuff
> ls /tmp/*.vdo

πŸ’– EMBEDDING IN PYTHON APPLICATIONS πŸ’–

okay so here's the tea: vncdotool is built on the Twisted framework (<http://twistedmatrix.com/>), which means it's literally made to vibe with other Twisted applications. But bestie, what if you don't wanna rewrite your whole app in Twisted? Mood. That's why vncdotool ships a compatibility layer 🫢 β€” it spins up a separate thread to run the Twisted reactor and chats with your main program through a thread-safe Queue.

⚠️ Warning: so the Twisted reactor runs as a daemon thread, BUT the reactor itself is gonna start extra worker threads, and those ones are not daemon threads. Which means you must shut the reactor down explicitly by calling vncdotool.api.shutdown(). If you don't, your application will not terminate β€” those worker threads just keep running in the background forever like a party nobody ended 😭 And this applies even when you're using the API as a context manager: since the reactor cannot be restarted, it's a design decision to not shut it down at the end of the context. Because if it did, you couldn't use the API multiple times in the same process. Iconic tradeoff, honestly.

To use the synchronous API you can do the following:

from vncdotool import api
client = api.connect('vncserver', password=None)

The first argument passed to the connect() method is the VNC server to connect to, and it needs to be in the format address[:display|::port]. Like, exactly that format bestie, no freestyling. For example:

# connect to 192.168.1.1 on default port 5900
client = api.connect('192.168.1.1', password=None)

# connect to localhost on display :3 (port 5903)
client = api.connect('localhost:3', password=None)

# connect to myvncserver.com on port 5902 (two colons needed)
client = api.connect('myvncserver.com::5902', password=None)

Then you can call any of the methods available on vncdotool.client.VNCDoToolClient and they will block until completion. For example:

client.captureScreen('screenshot.png')
client.keyPress('enter')
client.expectScreen('login_success.png', maxrms=10)

It is possible to set a per-client timeout in seconds to prevent calls from blocking indefinitely. ⏰

client.timeout = 10
try:
    client.captureScreen('screenshot.png')
except TimeoutError:
    print('Timeout when capturing screen')

In case of too many timeout errors, it is recommended to reset the client connection via the disconnect and connect() methods. Just like, refresh the vibe, yk?

The vncdotool.client.VNCDoToolClient supports the context manager protocol. Slay. πŸ’…

with api.connect('vnchost:display') as client:
    client.captureScreen('screenshot.png')

The synchronous API can be used to automate the starting of a Virtual Machine or other application:

vmtool.start('myvirtualmachine.img')
client.connect('vmaddress::5950')
client.expectScreen('booted.png')
for k in 'username':
    client.keyPress(k)
client.keyPress('enter')
for k in 'password':
    client.keyPress(k)
client.keyPress('enter')
client.expectScreen('loggedin.png')
client.disconnect()

# continue with your testing session or other work

✨ COMMAND REFERENCE ✨

here's the full roster of commands, no gatekeeping πŸŽ€

  • click BUTTON
  • capture FILENAME.PNG
  • drag X Y
  • expect FILENAME.PNG FUZZ
  • key KEY
  • keydown KEY
  • keyup KEY
  • move X Y
  • mousedown BUTTON
  • mousemove X Y
  • mouseup BUTTON
  • pause SECONDS
  • rcapture FILENAME.PNG X Y W H
  • rexpect FILENAME.PNG X Y FUZZ
  • type STRING

πŸ“œ RELEASE HISTORY πŸ“œ

the whole glow-up timeline, bestie. we love an evolution arc. πŸ¦‹

1.3.0 (2026-04-03)

  • Fix functional test suite (@phahn)
  • Python 3.12 is supported, Python 3.7 support removed (@phahn)
  • Improve documentation (@phahn)
  • Improve PEP-484 type hinting (@phahn)
  • Fix mouse dragging (@phahn)
  • Improve special key handling, fix key-down/key-up discrepancy with force_caps (@phahn, #270)
  • Allow specifying a format with captureScreen (@erjiang, #293)
  • Allow input literal - via client.keyPress with minus keyword (#302)
  • Fix: typefile and pastefile now accept - as filename for stdin (#307)
  • Switch from pycryptodomex to cryptography.io (@geofft, #278)
  • Remove transitive dependency zope.interface (#298)
  • Bump minimum Pillow version to 10.0.1 (#312)

1.2.0 (2023-06-06)

  • fixes for api.shutdown and disconnect raise exceptions, #256

1.1.0 (2023-04-01)

Huge thanks to @pmhahn for single handedly driving conversion to modern Python3, as well as cleaning up a ton of outstanding issues. πŸ‘‘

  • [BREAKING] drop python 2.x support, thanks @pmhahn
  • Use built-in Unittest and mock for testing
  • PEP-484 type hinting, thanks @pmhahn
  • Doc improvements, thanks @luke-jr, @pmhahn, @samiraguiar
  • Test for byte handling, thanks @ponty, refs #177
  • Internal implementation of DES replaced by PyCrotodomeX
  • Support for Apple Remote Desktop (ARD), thanks @andywgrant, @pmhahn
  • Support for pseudo-encoding LastRec, thanks @pmhahn
  • Support for Extended QEMU Key Events, thanks @pmhahn
  • Support IPv6 addresses for server connection, thanks @pmhahn
  • Bugfix, use configured log outputs over stdout, thanks @pevogam
  • Bugfix, handle invalid password, thanks @dozysun
  • Bugfixes for loggingproxy, thanks @joachimmetz, @pmhahn, @guicho271828

1.0.0 (2020-04-10)

  • add ZRLE encoding, thanks Adrian Weiler
  • drop python2 support
  • fix mouseDrag behaviour, thanks Samir Aguiar

0.13.0 (2019-11-21)

  • new flag --incremental-refreshes, increased compatibility of capture, thanks Amir Rossert
  • exit non-zero and print to stderr for unknown commands, thanks Amir Rossert

0.12.1 (2018-12-06)

  • bugfix expectRegion to use cropped images for compare, thanks Michael FΓΌrnschuß
  • direct support for building RPMs, thanks Plamen Dimitrov

0.12.0 (2018-04-07)

  • connect via UNIX sockets, thanks Matteo Cafasso
  • bugfix, XTightVNC initial connection, thanks Antti Kervinen

0.11.2 (2017-09-24)

  • fix version metadata, thanks Kevin Gottsman

0.11.1 (2017-07-23)

  • add api.client.disconnect()
  • fix python2.x compatibility, thanks Ostrosablin Vitaly

0.11.0 (2017-06-09)

  • enable PSEUDO_DESKTOP_SIZE_ENCODING by default to allow desktop resizing, thanks rebasegod
  • python 3.0 support, thanks jamtwister
  • added pastefile command, thanks Rogan Dawes
  • debian packaging improvements, thanks Alexander KlΓ€ser
  • fix loggingproxy, thanks Matthias Weckbecker

0.10.0 (2016-03-03)

  • drop official 2.6 support, it'll probably work for a while still
  • use frombytes rather than fromstring for compatibility with PIL
  • vnclog works with password protected servers using --password-required
  • exit more reliably after an error
  • use increatmental frameBufferUpdateRequests, appears to be compatible with more servers
  • include basic version negotiation with servers, thanks Ezra BΓΌhler

0.9.0 (2015-05-08)

  • add special keys [~!@#$%^&*()_+{}|:"<>?] to --force-caps, for servers that don't handle them, Tyler Oderkirk, Aragats Amirkhanyan
  • improve vnclog performance with TCP_NODELAY, Ian Britten
  • by default pause 10ms between sending commands, better compatibility with servers
  • better handle screen resizing, Daniel Stelter-Gliese
  • API, fix deadlocks due to threaded init of PIL, thanks Antti Kervinen
  • API, support password protected server, thanks Antti Kervinen
  • API, able to connect to multiple servers, Daniel Stelter-Gliese
  • drop official support for py2.4 and py2.5
  • use Pillow rather than PIL

Thanks to Jan SedlÑk, Daniel Stelter-Gliese, Antti Kervinen, Anatoly Techtonik, Tyler Oderkirk and Aragats Amirkhanyan for helping make this release possible 🫢

0.8.0 (2013-08-06)

  • improved documentation using sphinx
  • regional capture and expect that operate on a portion of the display
  • --force-caps, better compatibility when sending UPPERCASE to servers
  • --timeout, exit with an error after a given number of seconds
  • experimental synchronous API for easier integration with non-Twisted apps

0.3.0 (2012-12-22)

  • main program renamed to vncdo, vncdotool continues an alias for now
  • use host:display, host::port syntax like other vnc tools, removed -d
  • read/play commands from stdin or file
  • vnclog, creates scripts from captured interactive sessions
  • better control over mouse in screen captures with --nocursor and --localcursor
  • mousemove, sleep command aliases to match xdotool
  • keyup/keydown commands for more control over keypresses
  • send SetEncodings on connect, thanks Matias Suarez for fix
  • debian packaging
  • type "Hello World" now preserves capitalization
  • basic compatibility with VNC 4.0 servers, found in some KVMs
  • improved frameUpdate handling
  • --warp to replay script faster than real-time
  • --delay, insert a delay between sending commands

0.2.0 (2012-08-07)

  • add pause, mouseup, mousedown, drag commands
  • only require Twisted 11.1.0, so we can have py2.4 support
  • bugfixes, thanks Christopher Holm for reporting
    • vncdotool type -something now works
    • no longer silently fail for unsupported image formats

0.1.1 (2011-05-18)

  • add PIL to requires
  • fix bug where incorrect mouse button is sent

0.1.0 (2011-03-03)

  • first release
  • commands: press, type, move, click, capture, expect

🀝 CONTRIBUTING 🀝

Code and issue tracking is provided by Github (<https://github.com/sibson/vncdotool>). There's also a mailing list set up via Google Groups (<https://groups.google.com/forum/#!forum/vncdotool>). come hang out bestie, we don't bite 🫢


πŸ§‘β€πŸ’» CODE DOCUMENTATION πŸ§‘β€πŸ’»

api Module

Helpers to allow vncdotool to be integrated into other applications.

⚠️ Warning: EXPERIMENTAL. This feature is under development β€” your help testing and debugging is appreciated. it's giving beta energy, be gentle πŸ˜­πŸ™ˆ
vncdotool.api.connect(server: str) -> ThreadedVNCClientProxy
vncdotool.api.connect(server: str, password: str | None) -> ThreadedVNCClientProxy
vncdotool.api.connect(server: str, password: str | None, factory_class: type[VNCDoToolFactory]) -> ThreadedVNCClientProxy
vncdotool.api.connect(server: str, password: str | None, factory_class: type[VNCDoToolFactory], proxy: type[TProxy]) -> TProxy

🐍 client Module... wait, no, first the api stuff πŸ’…

Bestie we are still in the CODE DOCUMENTATION glow-up, and now we get to the functions. Strap in.

vncdotool.api.connect(server: str, password: str | None, factory_class: type[VNCDoToolFactory <#vncdotool.client.VNCDoToolFactory>], proxy: type[TProxy], timeout: float | None) -> TProxy

vncdotool.api.connect(server: str, password: str | None, factory_class: type[VNCDoToolFactory <#vncdotool.client.VNCDoToolFactory>], proxy: type[TProxy], timeout: float | None, username: str | None) -> TProxy

Two overloads, one destiny 🫢. So what does it do? It connects to a VNCServer and hands you back a Client instance that is usable in the main thread of non-Twisted Python Applications. Yes, main thread. Yes, non-Twisted. It just works, no cap.

>>> from vncdotool import api
>>> with api.connect('host') as client
>>>     client.keyPress('c')

Once you have that client, you may then call any regular VNCDoToolClient method on it from your own application code. Every. Single. One. Iconic.

Heads up: if you are using a GUI toolkit or other major async library, please read Choosing a Reactor and GUI Toolkit Integration over at <https://docs.twistedmatrix.com/en/stable/core/howto/choosing-reactor.html> for a better method of intergrating vncdotool. That's the officially blessed way, bestie β€” don't fight the reactor. 😀

vncdotool.api.shutdown() -> None

Shuts down the background thread running the Twisted reactor. That's it. That's the whole vibe. Tidy up after yourself, queen πŸ’….


🌈 client Module 🌈

Twisted based VNC client protocol and factory. Periodt.

πŸ’€ exception vncdotool.client.AuthenticationError

  • Bases: VNCDoException

Meaning? The VNC Server requires Authentication. That's it. Go find your password.

πŸ‘‘ class vncdotool.client.VMWareClient

  • Bases: VNCDoToolClient

Constant time, bestie:

SINGLE_PIXLE_UPDATE = b'\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00'

(yes that's the exact spelling, don't @ me)

dataReceived(data: bytes) -> None

Called whenever data is received. Use this method to translate to a higher-level message. Usually, some callback will be made upon the receipt of each complete protocol message.

Parameters:

  • data β€” a string of indeterminate length. Please keep in mind that you will probably need to buffer some data, as partial (or multiple) protocol messages may be received! I recommend that unit tests for protocols call through to this method with differing chunk sizes, down to one byte at a time. 😭 (one byte at a time, the audacity)

🧚 class vncdotool.client.VMWareFactory

  • Bases: VNCDoToolFactory
  • protocol β€” alias of VMWareClient

πŸ“ exception vncdotool.client.VNCDoException

  • Bases: Exception

That's the whole entry. Short and iconic.


⭐ class vncdotool.client.VNCDoToolClient

  • Bases: RFBClient

The main character, fr fr. Constants first:

MAX_DESKTOP_SIZE = 65536
SPECIAL_KEYS_US = '~!@#$%^&*()_+{}|:"<>?'
  • bell() β€” rings the bell πŸ””
  • buttons = 0
  • cmask: Image | None = None
  • cursor: Image | None = None
  • deferred: Deferred | None = None
  • encoding = 0
  • image_mode = 'RGBX'
  • screen: Image | None = None
  • x = 0
  • y = 0

Now the methods, and there are a LOT, so let's go πŸ¦‹:

captureRegion(fp: str | Path | IO[bytes], x: int, y: int, w: int, h: int, incremental: bool = False) -> Deferred

Save a region of the current display to filename. Cropped queen energy ✨.

captureScreen(fp: str | Path | IO[bytes], incremental: bool = False, format: str | None = None) -> Deferred

Capture and save the current VNC screen display to a file.

Parameters:

  • fp (TFile) β€” The destination where the screenshot will be saved. It can be a string path, a pathlib.Path object, or a file-like object opened in binary mode.
  • incremental (bool, optional):
    • False (default): Captures the entire screen.
    • True: Captures only the regions of the screen that have changed since the last capture.
  • format (str | None, optional):

commitUpdate(rectangles: list[Tuple[int, int, int, int]] | None = None) -> None

called after a series of updateRectangle(), copyRectangle() or fillRectangle() are finished.

Typicaly, here is the place to request the next screen update with framebufferUpdateRequest() with incremental=True.

Parameters:

  • rectangles β€” a list of tuples (x,y,w,h) with the updated rectangles.

connectionLost(reason: Failure) -> None

Called when the connection is shut down.

Clear any circular references here, and any external references to this Protocol. The connection has been closed.

@type reason: L{twisted.python.failure.Failure}

connectionMade() -> None

Called when a connection is made.

This may be considered the initializer of the protocol, because it is called when the connection is completed. For clients, this is called once the connection to the server has been established; for servers, this is called after an accept() call stops blocking and a socket has been received. If you need to send any greeting or initial message, do it here. Main character intro moment πŸŽ€.

copy_text(text: str) -> None

The server has new ISO 8859-1 (Latin-1) text in its cut buffer. (aka clipboard) Clipboard slay πŸ’….

drawCursor() -> None

Draws the cursor. Self-explanatory bestie.

expectRegion(filename: str, x: int, y: int, maxrms: float = 0) -> Deferred

Wait until a portion of the screen matches the target image.

The region compared is defined by the box (x, y), (x + image.width, y + image.height).

expectScreen(filename: str, maxrms: float = 0) -> Deferred

Wait until the display matches a target image.

Parameters:

  • filename β€” an image file to read and compare against.
  • maxrms β€” the maximum root mean square between histograms of the screen and target image.

keyDown(key: str) -> TClient

Holds a key down. 🫢

keyPress(key: str) -> TClient

Send a key press to the server.

Parameters:

  • key β€” either [a-z] or a from KEYMAP.

keyUp(key: str) -> TClient

Releases a key. Ty king.

mouseDown(button: int) -> TClient

Send a mouse button down at the last set position.

Parameters:

  • button β€” [1-n]

mouseDrag(x: int, y: int, step: int = 1) -> Iterator[Deferred]

Move the mouse point to position (x, y) in increments of step. Little steps, we love a journey πŸ¦‹.

mouseMove(x: int, y: int) -> TClient

Move the mouse pointer to position (x, y).

mousePress(button: int) -> TClient

Send a mouse click at the last set position.

Parameters:

  • button β€” [1-n]

mouseUp(button: int) -> TClient

Send mouse button released at the last set position.

Parameters:

  • button β€” [1-n]

paste(message: str) -> TClient

Pastes that message like it's nobody's business.

pause(duration: float) -> Deferred

A lil break. Deserved.

refreshScreen(incremental: bool = False) -> Deferred

Refreshes the screen, optionally incrementally.

setImageMode() -> None

Check support for PixelFormats announced by server or select client supported alternative.

updateCursor(x: int, y: int, width: int, height: int, image: bytes, mask: bytes) -> None

New cursor, focuses at (x, y).

updateDesktopSize(width: int, height: int) -> None

New desktop size of width*height.

updateRectangle(x: int, y: int, width: int, height: int, data: bytes) -> None

new bitmap data.

Parameters:

  • data β€” bytes in the pixel format set up earlier.

vncConnectionMade() -> None

connection is initialized and ready. typicaly, the pixel format is set here.

vncRequestPassword() -> None

a password is needed to log on, use sendPassword() to send one.


🌸 class vncdotool.client.VNCDoToolFactory

  • Bases: RFBFactory
clientConnectionFailed(connector: <InterfaceClass twisted.internet.interfaces.IConnector>, reason: Failure) -> None

Called when a connection has failed to connect.

It may be useful to call connector.connect() β€” this will reconnect.

@type reason: L{twisted.python.failure.Failure}

clientConnectionLost(connector: <InterfaceClass twisted.internet.interfaces.IConnector>, reason: Failure) -> None

Called when an established connection is lost.

It may be useful to call connector.connect() β€” this will reconnect.

@type reason: L{twisted.python.failure.Failure}

clientConnectionMade(protocol: VNCDoToolClient <#vncdotool.client.VNCDoToolClient>) -> None

Fires when the client connection is made. πŸŽ‰

Now the attributes, and there are many, so admire the collection bestie:

  • force_caps = False
  • last_rect = True
  • nocursor = False
  • password: str | None = None
  • protocol β€” alias of VNCDoToolClient
  • pseudocursor = False
  • pseudodesktop = True
  • qemu_extended_key = True
  • shared = True
  • username: str | None = None

πŸ”₯ vncdotool.client.factory_connect(factory: VNCDoToolFactory <#vncdotool.client.VNCDoToolFactory>, host: str, port: int, family: AddressFamily) -> None

Wires a factory up to a host, port and address family. Boom. Connected.


πŸ’œ rfb Module πŸ’œ

RFB protocol implementattion, client side.

Override RFBClient and RFBFactory in your application. See vncviewer.py for an example.

Reference: <http://www.realvnc.com/docs/rfbproto.pdf>

🌈 class vncdotool.rfb.AuthTypes(*values)

  • Bases: IntEnumLookup

RFC 6143 <https://datatracker.ietf.org/doc/html/rfc6143.html> Β§7.1.2. Security Handshake.

The values, all of them, exactly as they are:

APPLE_31 = 31
APPLE_32 = 32
APPLE_33 = 33
APPLE_34 = 34
APPLE_35 = 35
DIFFIE_HELLMAN = 30
INTEGRATED_SSH = 24
INVALID = 0
MD5 = 21

Nine auth types and we're only getting started... πŸ’€

…and the rest of the auth constants, bestie, in one tidy little pile:

MSLOGON2 = 113

NONE = 1

REALVNC_10 = 10

REALVNC_11 = 11

REALVNC_12 = 12

REALVNC_128 = 128

REALVNC_131 = 131

REALVNC_132 = 132

REALVNC_134 = 134

REALVNC_14 = 14

REALVNC_15 = 15

REALVNC_192 = 192

REALVNC_3 = 3

REALVNC_4 = 4

REALVNC_7 = 7

REALVNC_8 = 8

REALVNC_9 = 9

RSA_AES = 5

RSA_AES256 = 129

RSA_AES256_2STEP = 133

RSA_AES256_UNENCRYPTED = 130

RSA_AES_2STEP = 13

RSA_AES_UNENCRYPTED = 6

SASL = 20

SECURE_TUNNEL = 23

TIGHT = 16

TLS = 18

ULTRA = 17

VENCRYPT = 19

VNC_AUTHENTICATION = 2

XVP = 22

🌈 class vncdotool.rfb.Encoding(*values)

Bases: IntEnumLookup

This is the encoding-type you hand over to setEncodings(). Every vibe a server could possibly serve you, right here πŸ‘‡

APPLE_1000 = 1000

APPLE_1001 = 1001

APPLE_1002 = 1002

APPLE_1011 = 1011

APPLE_1100 = 1100

APPLE_1101 = 1101

APPLE_1102 = 1102

APPLE_1103 = 1103

APPLE_1104 = 1104

APPLE_1105 = 1105

CACHE = 4294901760

CACHE_ENABLE = 4294901761

CACHE_ZIP = 4294901767

CAR_CONNECTIVITY_523 = -523

CLIENT_REDIRECT = -311

COPY_RECTANGLE = 1

CORRE = 4

ENABLE_KEEP_ALIVE = 4294934529

FTP_PROTOCOl_VERSION = 4294934530

H264 = 20

HEXTILE = 5

HITACHI_ZYWRLE = 17

JPEG = 21

JPEG_23 = -23

JPEG_24 = -24

JPEG_25 = -25

JPEG_26 = -26

JPEG_27 = -27

JPEG_28 = -28

JPEG_29 = -29

JPEG_30 = -30

JPEG_31 = -31

JPEG_32 = -32

JRLE = 22

KEYBOARD_LED_STATE = 4294836224

LIBVNCSERVER_0XFFFE0004 = 4294836228

LIBVNCSERVER_219 = -219

LIBVNCSERVER_220 = -220

LIBVNCSERVER_221 = -221

LIBVNCSERVER_222 = -222

OLIVE_CALL_CONTROL = -310

OPEN_H264 = 50

PLUGIN_STREAMING = 3231835599

POINTER_POS = -225

POPA = -306

PSEUDO_COMPRESSION_LEVEL_247 = -247

PSEUDO_COMPRESSION_LEVEL_248 = -248

PSEUDO_COMPRESSION_LEVEL_249 = -249

PSEUDO_COMPRESSION_LEVEL_250 = -250

PSEUDO_COMPRESSION_LEVEL_251 = -251

PSEUDO_COMPRESSION_LEVEL_252 = -252

PSEUDO_COMPRESSION_LEVEL_253 = -253

PSEUDO_COMPRESSION_LEVEL_254 = -254

PSEUDO_COMPRESSION_LEVEL_255 = -255

PSEUDO_COMPRESSION_LEVEL_256 = -256

PSEUDO_CONTINUOUS_UPDATES = -313

PSEUDO_CURSOR = -239

PSEUDO_CURSOR_WITH_ALPHA = -314

PSEUDO_DESKTOP_NAME = -307

PSEUDO_DESKTOP_SIZE = -223

PSEUDO_EXTENDED_CLIPBOARD = 3231835598

PSEUDO_EXTENDED_DESKTOP_SIZE = -308

PSEUDO_FENCE = -312

PSEUDO_GII = -305

PSEUDO_JPEG_FINE_GRAINED_QUALITY_LEVEL = -412

PSEUDO_JPEG_SUBSAMLING_LEVEL = -763

PSEUDO_LAST_RECT = -224

PSEUDO_QEMU_AUDIO = -259

PSEUDO_QEMU_EXTENDED_KEY_EVENT = -258

PSEUDO_QEMU_LED_STATE = -261

PSEUDO_QEMU_POINTER_MODTION_CHANGE = -257

PSEUDO_VMWARE_CURSOR = 1464686180

PSEUDO_VMWARE_CURSOR_POSITION = 1464686182

PSEUDO_VMWARE_CURSOR_STATE = 1464686181

PSEUDO_VMWARE_DISPLAY_MODE_CHANGE = 1464686185

PSEUDO_VMWARE_KEY_REPEAT = 1464686183

PSEUDO_VMWARE_LED_STATE = 1464686184

PSEUDO_VMWARE_VIRTUAL_MACHINE_STATE = 1464686186

PSEUDO_XVO = -309

PSEUDO_X_CURSOR = -240

QEMU_262 = -262

RAW = 0

REAL_1024 = 1024

RRE = 2

SERVER_IDENTITY = 4294836227

SERVER_STATE = 4294934528

SESSION = 4294934531

SOLID_COLOR = 4294901765

SOL_MONO_ZIP = 4294901768

SUPPORTED_ENCODINGS = 4294836226

SUPPORTED_MESSAGES = 4294836225

TIGHT = 7

TIGHT_1 = -1

TIGHT_226 = -226

TIGHT_241 = -241

TIGHT_33 = -33

TIGHT_PNG = -260

TRLE = 15

ULTRA = 9

ULTRA2 = 10

ULTRA_ZIP = 4294901769

VA_H264 = 1211250228

VMWARE_0X574D5600 = 1464686080

VMWARE_273 = -273

XOR_ENABLE = 4294901766

XOR_MONO_RECT_ZLIB = 4294901763

XOR_MULTI_COLOR_ZLIB = 4294901764

XOR_ZLIB = 4294901762

ZLIB = 6

ZLIBHEX = 8

ZRLE = 16

And the lil methods hanging off it:

  • classmethod lookup(value: int) -> object β€” ya boi, find the member by its number πŸ’…
  • static s32(value: int) -> int β€” cast that value into a signed 32-bit int.

✨ class vncdotool.rfb.HextileEncoding(*values)

Bases: IntFlag

Straight from RFC 6153 β€” https://datatracker.ietf.org/doc/html/rfc6153.html β€” Β§7.7.4. Hextile Encoding. Reading the RFC is the assignment, bestie, but here are the flags so you don't have to squint πŸ”

ANY_SUBRECTS = 8

BACKGROUND_SPECIFIED = 2

FOREGROUND_SPECIFIED = 4

RAW = 1

SUBRECTS_COLORED = 16

πŸ’… class vncdotool.rfb.IntEnumLookup(new_class_name, /, names, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

The glow-up edition of IntEnum β€” it keeps a lookup table so you can pull a member straight out by its value.

  • classmethod lookup(value: int) -> object β€” give it a number, get the matching member back. Iconic behavior, fr 🫢

πŸ¦‹ class vncdotool.rfb.MsgS2C(*values)

Bases: IntEnumLookup

Server-to-client messages, per RFC 6143 β€” https://datatracker.ietf.org/doc/html/rfc6143.html β€” Β§7.6. Server-to-Client Messages. Everything the server can yell at you, catalogued 🌸

BELL = 2

CAR_CONNECTIVITY = 128

END_OF_CONTINUOUS_UPDATES = 150

FILE_TRANSFER = 7

FRAMEBUFFER_UPDATE = 0

GII_SERVER_MESSAGE = 253

KEEP_ALIVE = 13

KEY_FRAME_UPDATE = 5

OLIVE_CALL_CONTROL = 249

QEMU_SERVER_MESSAGE = 255

RESIZE_FRAME_BUFFER_15 = 15

RESIZE_FRAME_BUFFER_4 = 4

SERVER_CUT_TEXT = 3

SERVER_FENCE = 248

SERVER_STATE = 173

SET_COLOUR_MAP_ENTRIES = 1

TEXT_CHAT = 11

TIGHT = 252

ULTRA_10 = 10

ULTRA_12 = 12

ULTRA_14 = 14

ULTRA_6 = 6

ULTRA_8 = 8

ULTRA_9 = 9

VMWARE_127 = 127

VMWARE_254 = 254

XVP_SERVER_MESSAGE = 250

πŸ“ class vncdotool.rfb.PixelFormat(bpp: int = 32, depth: int = 24, bigendian: bool = False, truecolor: bool = True, redmax: int = 255, greenmax: int = 255, bluemax: int = 255, redshift: int = 0, greenshift: int = 8, blueshift: int = 16)

Bases: object

The pixel format data structure, exactly as RFC 6143 β€” https://datatracker.ietf.org/doc/html/rfc6143.html β€” Β§7.4. Pixel Format Data Structure describes it. All the defaults you could ever want πŸ’–

  • STRUCT: ClassVar = Struct('!BB??HHHBBBxxx')
  • VALIDATE: ClassVar = False
  • bigendian: bool = False
  • bluemax: int = 255
  • blueshift: int = 16
  • bpp: int = 32
  • property bypp: int β€” bytes per pixel, and yes the name is a little cursed, but it's OUR cursed πŸ’€
  • depth: int = 24
  • classmethod from_bytes(block: bytes) -> PixelFormat <#vncdotool.rfb.PixelFormat> β€” build a PixelFormat right out of a block of bytes.
  • greenmax: int = 255
  • greenshift: int = 8
  • redmax: int = 255
  • redshift: int = 0
  • to_bytes() -> bytes β€” flip it around and dump the whole thing back into bytes.
  • truecolor: bool = True

πŸ‘‘ class vncdotool.rfb.RFBClient

Bases: Protocol

This is the main character right here. Everything the client side of RFB does lives on this class ✨

Class-level constants, all of them:

MAX_CLIENT_VERSION = (3, 8)

SUPPORTED_AUTHS = {AuthTypes.NONE, AuthTypes.VNC_AUTHENTICATION, AuthTypes.DIFFIE_HELLMAN}

SUPPORTED_ENCODINGS = {Encoding.PSEUDO_QEMU_EXTENDED_KEY_EVENT, Encoding.PSEUDO_CURSOR, Encoding.PSEUDO_LAST_RECT, Encoding.PSEUDO_DESKTOP_SIZE, Encoding.RAW, Encoding.COPY_RECTANGLE, Encoding.RRE, Encoding.CORRE, Encoding.HEXTILE, Encoding.ZRLE}

SUPPORTED_SERVER_VERSIONS = {(3, 3), (3, 7), (3, 8), (3, 889), (4, 0), (4, 1), (5, 0)}

Now the methods, alphabetically, no crumbs left behind:

  • ardRequestCredentials() -> None β€” asks for the Apple Remote Desktop credentials.
  • beginUpdate() -> None β€” gets called before a whole series of updateRectangle(), copyRectangle() or fillRectangle() calls. It's the "we're about to go" moment 🏁
  • bell() β€” ding πŸ””
  • property bypp: int β€” bytes per pixel, same energy as over in PixelFormat.
  • clientCutText(message: str) -> None β€” the client has new ISO 8859-1 (Latin-1) text sitting in its cut buffer. Aka the clipboard, bestie βœ‚οΈ
  • commitUpdate(rectangles: list[Tuple[int, int, int, int]] | None = None) -> None β€” the wrap-up call, fired after a run of updateRectangle(), copyRectangle() or fillRectangle() is done.

Usually this is where you ask for the next screen update by calling framebufferUpdateRequest() with incremental=True. Door's open, come back with more pixels 🫢

Parameters:

  • rectangles β€” a list of tuples (x,y,w,h) holding the rectangles that got updated.
  • copyRectangle(srcx: int, srcy: int, x: int, y: int, width: int, height: int) -> None β€” this one's for copyrect encoding. It copies the given rectangle (src, srxy, width, height) over to the target coords (x,y).
  • copy_text(text: str) -> None β€” the server has new ISO 8859-1 (Latin-1) text in its cut buffer. Aka the clipboard again β€” this one's the server's turn πŸ’…
  • dataReceived(data: bytes) -> None β€” fires every single time data shows up. This is where you translate raw bytes into higher-level messages, and normally some callback gets triggered once each complete protocol message lands.

@param data: a string of indeterminate length. Please keep in mind that you'll probably need to buffer some of it, because you can get partial protocol messages… or multiple of them at once! The recommendation is that unit tests for protocols call through to this method with chunk sizes that keep shrinking, all the way down to one byte at a time. No pressure though 😭

  • expect(handler: Callable[[...], None], size: int, *args: Any, **kwargs: Any) -> None β€” registers a handler that waits for a specific amount of incoming data.
  • fillRectangle(x: int, y: int, width: int, height: int, color: bytes) -> None β€” fills that area with the color. Paint bucket mode 🎨

Parameters:

  • color β€” bytes in the pixel format you set up earlier.
  • framebufferUpdateRequest(x: int = 0, y: int = 0, width: int | None = None, height: int | None = None, incremental: bool = False) -> None
  • keyEvent(key: int, down: bool = True) -> None β€” so for basically every normal key, the "keysym" is literally just the matching ASCII value, no drama πŸ’…. The other common ones live in the KEY_ constants, go look there bestie.
  • pointerEvent(x: int, y: int, buttonmask: int = 0) -> None β€” this is giving either pointer movement or a pointer button press/release, pick your fighter. The pointer is now at (x-position, y-position) ✨, and the current state of buttons 1 to 8 is represented by bits 0 to 7 of button-mask respectively β€” 0 means up, 1 means down (pressed). Periodt.
  • sendPassword(password: str) -> None β€” send password πŸ”‘
  • setEncodings(list_of_encodings: Collection[Encoding <#vncdotool.rfb.Encoding>]) -> None
  • setPixelFormat(pixel_format: PixelFormat <#vncdotool.rfb.PixelFormat>) -> None
  • set_color_map(first: int, colors: list[tuple[int, int, int]]) -> None β€” the server is using a new color map 🎨. Not me, it's the server.
  • updateCursor(x: int, y: int, width: int, height: int, image: bytes, mask: bytes) -> None β€” new cursor, and it focuses at (x, y) πŸ‘‘
  • updateDesktopSize(width: int, height: int) -> None β€” new desktop size of width*height.
  • updateRectangle(x: int, y: int, width: int, height: int, data: bytes) -> None β€” new bitmap data πŸ–ΌοΈ

Parameters

  • data -- bytes in the pixel format set up earlier.
  • vncAuthFailed(reason: Failure) -> None β€” called when the authentication failed. the connection is closed. πŸ’€ rip.
  • vncConnectionMade() -> None β€” connection is initialized and ready 🫢. typicaly, the pixel format is set here.
  • vncRequestPassword() -> None β€” a password is needed to log on, use sendPassword() to send one.

πŸ’œ class vncdotool.rfb.RFBFactory(password: str | None = None, shared: bool = False) πŸ’œ

Bases: ClientFactory

A factory for remote frame buffer connections. Like, it makes the connections. That's the whole vibe.

protocol β€” alias of RFBClient


πŸŽ€ command Module πŸŽ€

Command line interface to interact with a VNC Server 🌸


exception vncdotool.command.CommandParseError

Bases: RuntimeError


πŸ¦‹ class vncdotool.command.ExitingProcess πŸ¦‹

Bases: ProcessProtocol

  • errReceived(data: bytes) -> None β€” Some data was received from stderr. πŸ‘€
  • processExited(reason: Failure) -> None β€” this will be called when the subprocess exits ✨

@type reason: L{twisted.python.failure.Failure}


exception vncdotool.command.TimeoutError

Bases: RuntimeError


🌈 class vncdotool.command.VNCDoCLIClient 🌈

Bases: VNCDoToolClient

  • vncRequestPassword() -> None β€” a password is needed to log on, use sendPassword() to send one.

✨ class vncdotool.command.VNCDoCLIFactory ✨

Bases: VNCDoToolFactory

  • clientConnectionFailed(connector: <InterfaceClass twisted.internet.interfaces.IConnector>, reason: Failure) -> None β€” Called when a connection has failed to connect. 😭

It may be useful to call connector.connect() - this will reconnect.

@type reason: L{twisted.python.failure.Failure}

  • clientConnectionLost(connector: <InterfaceClass twisted.internet.interfaces.IConnector>, reason: Failure) -> None β€” Called when an established connection is lost. πŸ’”

It may be useful to call connector.connect() - this will reconnect.

@type reason: L{twisted.python.failure.Failure}

  • done(exit_code: int) -> None
  • error(reason: Failure) -> None
  • protocol β€” alias of VNCDoCLIClient

πŸ“ class vncdotool.command.VNCDoToolOptionParser(usage=None, option_list=None, option_class=<class 'optparse.Option'>, version=None, conflict_handler='error', description=None, formatter=None, add_help_option=True, prog=None, epilog=None) πŸ“

Bases: OptionParser

  • format_help(formatter: HelpFormatter | None = None) -> str

  • vncdotool.command.add_standard_options(parser: OptionParser) -> OptionParser
  • vncdotool.command.build_command_list(factory: VNCDoCLIFactory <#vncdotool.command.VNCDoCLIFactory>, args: list[str], delay: float | None = None, warp: float = 1.0, incremental_refreshes: bool = False) -> None
  • vncdotool.command.build_proxy(options: Values) -> VNCLoggingServerFactory <#vncdotool.loggingproxy.VNCLoggingServerFactory>
  • vncdotool.command.build_tool(options: Values, args: list[str]) -> VNCDoCLIFactory <#vncdotool.command.VNCDoCLIFactory>
  • vncdotool.command.log_connected(pcol: TClient) -> TClient
  • vncdotool.command.log_exceptions(type_: type[BaseException], value: BaseException, tb: TracebackType | None) -> None
  • vncdotool.command.parse_server(server: str) -> tuple[AddressFamily, str, int]
  • vncdotool.command.setup_logging(options: Values) -> None
  • vncdotool.command.vncdo() -> None
  • vncdotool.command.vnclog() -> None

πŸ’– loggingproxy Module πŸ’–

✨ class vncdotool.loggingproxy.MsgC2S(*values) ✨

Bases: IntEnumLookup

RFC 6143 <https://datatracker.ietf.org/doc/html/rfc6143.html> Β§7.5. Client-to-Server Messages. iykyk πŸ“œ

  • CAR_CONNECTIVITY = 128
  • CLIENT_CUT_TEXT = 6
  • CLIENT_FENCE = 248
  • ENABLE_CONTINUOUS_UPDATES = 150
  • FILE_TRANSFER = 7
  • FRAMEBUFFER_UPDATE_REQUEST = 3
  • GII_CLIENT_MESSAGE = 253
  • KEEP_ALIVE = 13
  • KEY_EVENT = 4
  • KEY_FRAME_REquest = 12
  • NOTIFY_PLUGIN_STREAMING = 80
  • OLIVE_CALL_CONTROL = 249
  • POINTER_EVENT = 5
  • QEMU_CLIENT_MESSAGE = 255
  • REQUEST_SESSION = 20
  • SET_DESKTOP_SIZE = 251
  • SET_ENCODING = 2
  • SET_PIXEL_FORMAT = 0
  • SET_SCALE = 8
  • SET_SCALE_FACTOR = 15
  • SET_SERVER_INPUT = 9
  • SET_SESSION = 21
  • SET_SW = 10
  • TEXT_CHAT = 11
  • TIGHT = 252
  • ULTRA_14 = 14
  • ULTRA_16 = 16
  • ULTRA_17 = 17
  • ULTRA_18 = 18
  • ULTRA_19 = 19
  • VMWARE_127 = 127
  • VMWARE_254 = 254
  • XVP_CLIENT_MESSAGE = 250

🧚 class vncdotool.loggingproxy.NullTransport 🧚

Bases: object

  • addressFamily = 0
  • loseConnection() -> None
  • setTcpNoDelay(enabled: bool) -> None
  • write(data: bytes) -> None
  • writeSequence(data: bytes) -> None

exception vncdotool.loggingproxy.ProtocolError

Bases: Exception

VNC Protocol error 🚨


🌸 class vncdotool.loggingproxy.QemuClientMessage(*values) 🌸

Bases: IntEnumLookup

QEMU Client Message <https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#qemu-client-message>

  • AUDIO = 1
  • EXTENDED_KEY_EVENT = 0

πŸ‘‘ class vncdotool.loggingproxy.RFBServer πŸ‘‘

Bases: Protocol

  • connectionMade() -> None β€” Called when a connection is made. πŸŽ‰

This may be considered the initializer of the protocol, because it is called when the connection is completed. For clients, this is called once the connection to the server has been established; for servers, this is called after an accept() call stops blocking and a socket has been received. If you need to send any greeting or initial message, do it here. the way that this is literally the vibe-setter...

  • dataReceived(data: bytes) -> None β€” Called whenever data is received. πŸ“₯

Use this method to translate to a higher-level message. Usually, some callback will be made upon the receipt of each complete protocol message.

@param data: a string of indeterminate length. Please keep in mind that you will probably need to buffer some data, as partial (or multiple) protocol messages may be received! I recommend that unit tests for protocols call through to this method with differing chunk sizes, down to one byte at a time.

  • handle_clientCutText(block: bytes) -> None
  • handle_framebufferUpdate(x: int, y: int, w: int, h: int, incremental: bool) -> None
  • handle_keyEvent(key: int, down: bool) -> None
  • handle_keyEventExtended(keysym: int, down: bool, keycode: int) -> None
  • handle_pointerEvent(x: int, y: int, buttonmask: int) -> None
  • handle_setEncodings(encodings: Sequence[int]) -> None
  • handle_setPixelFormat(pixel_format: PixelFormat <#vncdotool.rfb.PixelFormat>) -> None

πŸ’œ class vncdotool.loggingproxy.VNCLoggingClient πŸ’œ

Bases: VNCDoToolClient

Specialization of a VNCDoToolClient that will save screen captures πŸ“Έ obsessed.

  • capture_file: str | None = None
  • commitUpdate(rectangles: list[Tuple[int, int, int, int]] | None = None) -> None β€” called after a series of updateRectangle(), copyRectangle() or fillRectangle() are finished.

Typicaly, here is the place to request the next screen update with framebufferUpdateRequest() with incremental=True.

Parameters

  • rectangles -- a list of tuples (x,y,w,h) with the updated rectangles.

πŸŽ€ class vncdotool.loggingproxy.VNCLoggingClientFactory πŸŽ€

Bases: ProxyClientFactory

  • protocol β€” alias of VNCLoggingClientProxy

🫢 class vncdotool.loggingproxy.VNCLoggingClientProxy 🫢

Bases: ProxyClient

Accept data from a server and forward to logger and downstream client. It's giving middleman, but make it iconic ✨

   VNC server -> VNCLoggingClientProxy -> VNC client
                                       -> VNCLoggingClient
  • dataReceived(data: bytes) -> None β€” Called whenever data is received.

Use this method to translate to a higher-level message. Usually, some callback will be made upon the receipt of each complete protocol message.

  • @param data β€” a string of indeterminate length. Please keep in mind that you will probably need to buffer some data, because partial (or multiple) protocol messages may be received! I recommend that unit tests for protocols call through to this method with differing chunk sizes, down to one byte at a time. 🫢
  • ncaptures = 0
  • startLogging(peer: VNCLoggingServerProxy <#vncdotool.loggingproxy.VNCLoggingServerProxy>) -> None
  • vnclog: VNCLoggingClient <#vncdotool.loggingproxy.VNCLoggingClient> | None = None

πŸ‘‘ class vncdotool.loggingproxy.VNCLoggingServerFactory(host, port)

Bases: ProxyFactory β€” yes bestie, it inherits, it's giving legacy, it's iconic.

  • clientConnectionLost(client: VNCLoggingServerProxy <#vncdotool.loggingproxy.VNCLoggingServerProxy>) -> None
  • clientConnectionMade(client: VNCLoggingServerProxy <#vncdotool.loggingproxy.VNCLoggingServerProxy>) -> None
  • force_caps = False
  • getRecorder() -> Callable[[str], int]
  • last_rect = True
  • nocursor = False
  • output: IO[str] | str = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
  • password_required = False
  • protocol β€” alias of VNCLoggingServerProxy
  • pseudocursor = False
  • pseudodesktop = True
  • qemu_extended_key = True
  • shared = True

πŸ’… class vncdotool.loggingproxy.VNCLoggingServerProxy

Bases: ProxyServer, RFBServer

This one is the proxy in the middle β€” it decodes and logs RFB messages before sending them upstream. So the traffic flow is literally this:

VNC client -> VNCLoggingServerProxy -> VNC server
                                    -> RFBServer
  • buttons = 0
  • clientProtocolFactory β€” alias of VNCLoggingClientFactory
  • connectionLost(reason: Failure) -> None β€” called when the connection is shut down. Clear any circular references here, and any external references to this Protocol. The connection has been closed. @type reason: L{twisted.python.failure.Failure}
  • connectionMade() -> None β€” called when a connection is made. This may be considered the initializer of the protocol, because it is called when the connection is completed. For clients, this is called once the connection to the server has been established; for servers, this is called after an accept() call stops blocking and a socket has been received. If you need to send any greeting or initial message, do it here. ✨
  • dataReceived(data: bytes) -> None β€” called whenever data is received. Use this method to translate to a higher-level message. Usually, some callback will be made upon the receipt of each complete protocol message.

@param data: a string of indeterminate length. Please keep in mind that you will probably need to buffer some data, as partial (or multiple) protocol messages may be received! I recommend that unit tests for protocols call through to this method with differing chunk sizes, down to one byte at a time.

  • handle_keyEvent(key: int, down: bool) -> None
  • handle_pointerEvent(x: int, y: int, buttonmask: int) -> None
  • recorder: Callable[[str], int] | None = None
  • server: str | None = None

okay and if you wanna go hopping around the docs yourself, the vibes index is right here πŸ¦‹

  • Index <>
  • Module Index <>
  • Search Page <>

🌸 Author 🌸

Marc Sibson β€” the icon, the moment, the whole reason this page exists 🫢


2013-2024, Marc Sibson


and that's a wrap on the whole page, bestie!! πŸŽ€ this was vncdotool version 1.3.0, dated May 24, 2026, and it will forever live in your terminal as VNCDOTOOL(1) πŸ’… no cap, go automate some VNC, you absolute main character πŸ‘‘βœ¨

πŸ“¦ where this page comes from