VNCDOTOOL(1)
π 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:
[image: Actions Status] [image] <https://github.com/sibson/vndotool/actions>[image: ReadTheDocs] [image] <https://vncdotool.readthedocs.io/en/latest/>[image: Code style: black] [image] <https://github.com/psf/black>
π 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.
- Download Python, current 64-bit Windows Version, from Official Python (
https://python.org/downloads/) website (https://www.python.org/downloads/) - 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
- Make sure the boxes for
- Click
"Install"at the bottom
- Check the box for
- 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):
- Type
[Environment]::SetEnvironmentVariable("Path", "$env:Path;C:\Program Files\Python39\;C:\Program Files\Python39\Scripts\", "User")
python -m pip install --upgrade pip
pip install vncdotool
- At a Powershell prompt:
vncdo.exe --server som.eip.add.res type "Hello World"
- 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
vncdotoolagain, 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 BUTTONcapture FILENAME.PNGdrag X Yexpect FILENAME.PNG FUZZkey KEYkeydown KEYkeyup KEYmove X Ymousedown BUTTONmousemove X Ymouseup BUTTONpause SECONDSrcapture FILENAME.PNG X Y W Hrexpect FILENAME.PNG X Y FUZZtype 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
-viaclient.keyPresswithminuskeyword (#302) - Fix:
typefileandpastefilenow accept-as filename for stdin (#307) - Switch from
pycryptodomextocryptography.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.shutdownanddisconnectraise 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
mouseDragbehaviour, thanks Samir Aguiar
0.13.0 (2019-11-21)
- new flag
--incremental-refreshes, increased compatibility ofcapture, thanks Amir Rossert - exit non-zero and print to stderr for unknown commands, thanks Amir Rossert
0.12.1 (2018-12-06)
- bugfix
expectRegionto 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_ENCODINGby default to allow desktop resizing, thanks rebasegod - python 3.0 support, thanks jamtwister
- added
pastefilecommand, 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
frombytesrather thanfromstringfor compatibility with PIL vnclogworks 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
vnclogperformance withTCP_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,vncdotoolcontinues an alias for now - use
host:display,host::portsyntax 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
--nocursorand--localcursor mousemove,sleepcommand aliases to match xdotoolkeyup/keydowncommands for more control over keypresses- send
SetEncodingson 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
frameUpdatehandling --warpto replay script faster than real-time--delay, insert a delay between sending commands
0.2.0 (2012-08-07)
- add
pause,mouseup,mousedown,dragcommands - only require Twisted 11.1.0, so we can have py2.4 support
- bugfixes, thanks Christopher Holm for reporting
vncdotool type -somethingnow 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 ofVMWareClient
π 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 = 0cmask: Image | None = Nonecursor: Image | None = Nonedeferred: Deferred | None = Noneencoding = 0image_mode = 'RGBX'screen: Image | None = Nonex = 0y = 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, apathlib.Pathobject, 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):- See Pillow's list of image formats: <https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html>
- If set to
None, Pillow will determine the format based on the provided file name.
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 fromKEYMAP.
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 = Falselast_rect = Truenocursor = Falsepassword: str | None = Noneprotocolβ alias ofVNCDoToolClientpseudocursor = Falsepseudodesktop = Trueqemu_extended_key = Trueshared = Trueusername: 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 = Falsebigendian: bool = Falsebluemax: int = 255blueshift: int = 16bpp: int = 32property bypp: intβ bytes per pixel, and yes the name is a little cursed, but it's OUR cursed πdepth: int = 24classmethod from_bytes(block: bytes) -> PixelFormat <#vncdotool.rfb.PixelFormat>β build aPixelFormatright out of a block of bytes.greenmax: int = 255greenshift: int = 8redmax: int = 255redshift: int = 0to_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 ofupdateRectangle(),copyRectangle()orfillRectangle()calls. It's the "we're about to go" moment πbell()β ding πproperty bypp: intβ bytes per pixel, same energy as over inPixelFormat.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 ofupdateRectangle(),copyRectangle()orfillRectangle()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) -> NonekeyEvent(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 theKEY_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 β0means up,1means down (pressed). Periodt.sendPassword(password: str) -> Noneβ send password πsetEncodings(list_of_encodings: Collection[Encoding <#vncdotool.rfb.Encoding>]) -> NonesetPixelFormat(pixel_format: PixelFormat <#vncdotool.rfb.PixelFormat>) -> Noneset_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, usesendPassword()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, usesendPassword()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) -> Noneerror(reason: Failure) -> Noneprotocolβ alias ofVNCDoCLIClient
π 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) -> OptionParservncdotool.command.build_command_list(factory: VNCDoCLIFactory <#vncdotool.command.VNCDoCLIFactory>, args: list[str], delay: float | None = None, warp: float = 1.0, incremental_refreshes: bool = False) -> Nonevncdotool.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) -> TClientvncdotool.command.log_exceptions(type_: type[BaseException], value: BaseException, tb: TracebackType | None) -> Nonevncdotool.command.parse_server(server: str) -> tuple[AddressFamily, str, int]vncdotool.command.setup_logging(options: Values) -> Nonevncdotool.command.vncdo() -> Nonevncdotool.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 = 128CLIENT_CUT_TEXT = 6CLIENT_FENCE = 248ENABLE_CONTINUOUS_UPDATES = 150FILE_TRANSFER = 7FRAMEBUFFER_UPDATE_REQUEST = 3GII_CLIENT_MESSAGE = 253KEEP_ALIVE = 13KEY_EVENT = 4KEY_FRAME_REquest = 12NOTIFY_PLUGIN_STREAMING = 80OLIVE_CALL_CONTROL = 249POINTER_EVENT = 5QEMU_CLIENT_MESSAGE = 255REQUEST_SESSION = 20SET_DESKTOP_SIZE = 251SET_ENCODING = 2SET_PIXEL_FORMAT = 0SET_SCALE = 8SET_SCALE_FACTOR = 15SET_SERVER_INPUT = 9SET_SESSION = 21SET_SW = 10TEXT_CHAT = 11TIGHT = 252ULTRA_14 = 14ULTRA_16 = 16ULTRA_17 = 17ULTRA_18 = 18ULTRA_19 = 19VMWARE_127 = 127VMWARE_254 = 254XVP_CLIENT_MESSAGE = 250
π§ class vncdotool.loggingproxy.NullTransport π§
Bases: object
addressFamily = 0loseConnection() -> NonesetTcpNoDelay(enabled: bool) -> Nonewrite(data: bytes) -> NonewriteSequence(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 = 1EXTENDED_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) -> Nonehandle_framebufferUpdate(x: int, y: int, w: int, h: int, incremental: bool) -> Nonehandle_keyEvent(key: int, down: bool) -> Nonehandle_keyEventExtended(keysym: int, down: bool, keycode: int) -> Nonehandle_pointerEvent(x: int, y: int, buttonmask: int) -> Nonehandle_setEncodings(encodings: Sequence[int]) -> Nonehandle_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 = NonecommitUpdate(rectangles: list[Tuple[int, int, int, int]] | None = None) -> Noneβ called after a series ofupdateRectangle(),copyRectangle()orfillRectangle()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 ofVNCLoggingClientProxy
π«Ά 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 = 0startLogging(peer: VNCLoggingServerProxy <#vncdotool.loggingproxy.VNCLoggingServerProxy>) -> Nonevnclog: 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>) -> NoneclientConnectionMade(client: VNCLoggingServerProxy <#vncdotool.loggingproxy.VNCLoggingServerProxy>) -> Noneforce_caps = FalsegetRecorder() -> Callable[[str], int]last_rect = Truenocursor = Falseoutput: IO[str] | str = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>password_required = Falseprotocolβ alias ofVNCLoggingServerProxypseudocursor = Falsepseudodesktop = Trueqemu_extended_key = Trueshared = 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 = 0clientProtocolFactoryβ alias ofVNCLoggingClientFactoryconnectionLost(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 anaccept()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) -> Nonehandle_pointerEvent(x: int, y: int, buttonmask: int) -> Nonerecorder: Callable[[str], int] | None = Noneserver: 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 π«Ά
π Copyright π
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
- ubuntu stonking: vncdotool 1.3.0-1 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms