Skip to content

Commit 0ced1e7

Browse files
committed
Initialize
0 parents  commit 0ced1e7

10 files changed

+367
-0
lines changed

.gitignore

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
env/
12+
build/
13+
develop-eggs/
14+
dist/
15+
downloads/
16+
eggs/
17+
.eggs/
18+
lib/
19+
lib64/
20+
parts/
21+
sdist/
22+
var/
23+
*.egg-info/
24+
.installed.cfg
25+
*.egg
26+
27+
# PyInstaller
28+
# Usually these files are written by a python script from a template
29+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
30+
*.manifest
31+
*.spec
32+
33+
# Installer logs
34+
pip-log.txt
35+
pip-delete-this-directory.txt
36+
37+
# Unit test / coverage reports
38+
htmlcov/
39+
.tox/
40+
.coverage
41+
.coverage.*
42+
.cache
43+
nosetests.xml
44+
coverage.xml
45+
*,cover
46+
47+
# Translations
48+
*.mo
49+
*.pot
50+
51+
# Django stuff:
52+
*.log
53+
54+
# Sphinx documentation
55+
docs/_build/
56+
57+
# PyBuilder
58+
target/

COPYING

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2+
Version 2, December 2004
3+
4+
Copyright (C) 2004 Sam Hocevar <[email protected]>
5+
6+
Everyone is permitted to copy and distribute verbatim or modified
7+
copies of this license document, and changing it is allowed as long
8+
as the name is changed.
9+
10+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12+
13+
0. You just DO WHAT THE FUCK YOU WANT TO.

MANIFEST.in

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include README.rst

README.rst

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
=======
2+
Vncdesk
3+
=======
4+
5+
*Vncdesk* was originally developed for scaling up applications on high DPI
6+
screens. Applications run in VNC desktops.
7+
8+
9+
Installation
10+
============
11+
12+
Install dependencies:
13+
14+
* Python 3
15+
16+
* TigerVNC_ 1.4 or a compatible VNC server
17+
18+
* gtk-vnc_ 0.5 or compatible
19+
20+
Run with sufficient permissions::
21+
22+
python setup.py install
23+
24+
25+
Usage
26+
=====
27+
28+
Configuration for each desktop goes into a numbered directory below
29+
``~/.vncdesk``. For example the configuration in ``~/.vncdesk/2/`` can be run
30+
with::
31+
32+
vncdesk 2
33+
34+
Files:
35+
36+
* ``settings.ini``, by example::
37+
38+
[desktop]
39+
width = 1024
40+
height = 768
41+
42+
* ``startup``: Startup script. Environment variables provided:
43+
44+
- ``WIDTH``, ``HEIGHT``: Desktop size.
45+
46+
- ``DISPLAY``: Display of the VNC server.
47+
48+
- ``GUEST_DISPLAY``: Display of the VNC client.
49+
50+
Example::
51+
52+
#!/bin/sh
53+
xrdb -merge Xresources
54+
exec xfig -geometry ${WIDTH}x$HEIGHT+0+0
55+
56+
* Application specific files, for example ``Xresources``::
57+
58+
xfig*image_editor: DISPLAY=$GUEST_DISPLAY xdg-open
59+
xfig*pdfviewer: DISPLAY=$GUEST_DISPLAY xdg-open
60+
xfig*browser: DISPLAY=$GUEST_DISPLAY xdg-open
61+
62+
* ``.password``: Generated every time anew, to password protect the connection
63+
also from other users on the same system.
64+
65+
GDK 3 can scale the VNC viewer::
66+
67+
GDK_SCALE=2
68+
69+
70+
Releasing a new version
71+
=======================
72+
73+
* Use versioning scheme: `major.minor.patch`_
74+
75+
* Tag version in Git.
76+
77+
78+
Coding convertions
79+
==================
80+
81+
* Maximum line length: 80 characters
82+
83+
* Comments in reStructuredText.
84+
85+
86+
License
87+
=======
88+
89+
Except where noted otherwise, files are licensed under the WTFPL.
90+
91+
Copyright © 2015 `Felix E. Klee <mailto:[email protected]>`
92+
93+
This work is free. You can redistribute it and/or modify it under the terms of
94+
the Do What The Fuck You Want To Public License, Version 2, as published by Sam
95+
Hocevar. See the COPYING file for more details.
96+
97+
98+
.. _TigerVNC: http://tigervnc.org/
99+
.. _major.minor.patch: http://semver.org/
100+
.. _gtk-vnc: https://wiki.gnome.org/Projects/gtk-vnc

bin/vncdesk

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/python
2+
3+
import vncdesk
4+
5+
vncdesk.main()

setup.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from distutils.core import setup
2+
3+
setup(
4+
name = "vncdesk",
5+
version = "1.0.0",
6+
author = "Felix E. Klee",
7+
author_email = "[email protected]",
8+
url = "https://github.com/feklee/vncdesk",
9+
packages = ["vncdesk"],
10+
scripts = ["bin/vncdesk"],
11+
license = "WTFPL",
12+
description = "Runs applications via VNC. Allows scaling applications.",
13+
long_description = open('README.rst').read()
14+
)

vncdesk/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from vncdesk.main import main

vncdesk/main.py

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/python
2+
3+
from gi.repository import Gtk
4+
from gi.repository import Gdk
5+
from gi.repository import GtkVnc
6+
7+
from vncdesk import vnc_server
8+
from sys import argv
9+
from vncdesk.util import exit_on_error
10+
11+
def vnc_initialized(src, window):
12+
print("Connection initialized")
13+
window.show_all()
14+
window.set_size_request(vnc_server.width, vnc_server.height)
15+
window.set_resizable(False)
16+
17+
def quit_all(widget = None):
18+
vnc_server.terminate()
19+
Gtk.main_quit()
20+
21+
def vnc_disconnected(src):
22+
print("Disconnected from server")
23+
quit_all()
24+
25+
def exit_with_usage():
26+
exit_on_error("Usage: " + argv[0] + " NUMBER")
27+
28+
def read_cmd_line():
29+
if len(argv) != 2:
30+
exit_with_usage()
31+
32+
try:
33+
return int(argv[1])
34+
except ValueError:
35+
exit_with_usage()
36+
37+
def main():
38+
vnc_server.start(read_cmd_line())
39+
40+
window = Gtk.Window()
41+
vnc = GtkVnc.Display()
42+
43+
window.add(vnc)
44+
window.connect("destroy", quit_all)
45+
46+
vnc.realize()
47+
vnc.set_pointer_local(False)
48+
49+
vnc.set_credential(GtkVnc.DisplayCredential.PASSWORD, vnc_server.password)
50+
51+
vnc.open_host("localhost", str(vnc_server.port))
52+
53+
vnc.connect("vnc-initialized", vnc_initialized, window)
54+
vnc.connect("vnc-disconnected", vnc_disconnected)
55+
56+
Gtk.main()

vncdesk/util.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from sys import exit, stderr
2+
3+
def exit_on_error(msg):
4+
stderr.write(msg + "\n")
5+
exit(1)

vncdesk/vnc_server.py

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from os import path, environ, kill, system, chdir, access, X_OK
2+
import string
3+
import signal
4+
from time import sleep
5+
import uuid
6+
import threading
7+
import configparser
8+
from vncdesk.util import exit_on_error
9+
10+
def read_settings():
11+
global width, height
12+
13+
try:
14+
config = configparser.ConfigParser()
15+
config.read('settings.ini')
16+
width = int(config['desktop']['width'])
17+
height = int(config['desktop']['height'])
18+
except:
19+
exit_on_error("Cannot read settings or settings are corrupt")
20+
21+
def set_environ():
22+
global _display, width, height
23+
environ["WIDTH"] = str(width)
24+
environ["HEIGHT"] = str(height)
25+
environ["GUEST_DISPLAY"] = environ["DISPLAY"]
26+
environ["DISPLAY"] = _display
27+
28+
def terminate():
29+
global _xvnc_lock_filename
30+
31+
if path.isfile(_xvnc_lock_filename):
32+
pid = int(open(_xvnc_lock_filename, 'r').read())
33+
kill(pid, signal.SIGTERM)
34+
35+
def wait_for_xvnc():
36+
while not path.isfile(_xvnc_lock_filename):
37+
sleep(0.1)
38+
39+
def start_xvnc():
40+
global _display, width, height, _number, port
41+
42+
port = 5900 + _number
43+
cmd = " ".join(["Xvnc",
44+
_display,
45+
"-desktop xfig",
46+
"-geometry " + str(width) + "x" + str(height),
47+
"-rfbauth " + _password_filename,
48+
"-rfbport " + str(port),
49+
"-pn",
50+
"&"])
51+
terminate()
52+
system(cmd)
53+
wait_for_xvnc()
54+
55+
def write_password_to_file():
56+
global _password_filename
57+
_password_filename = ".passwd"
58+
cmd = ";".join([
59+
"rm -f " + _password_filename,
60+
"umask 177",
61+
"|".join([
62+
"echo '" + password + "'",
63+
"vncpasswd -f >" + _password_filename
64+
])
65+
])
66+
system(cmd)
67+
68+
def create_password():
69+
global password
70+
password = str(uuid.uuid4())
71+
write_password_to_file()
72+
73+
def check_startup(filename):
74+
if not path.isfile(filename) or not access(filename, X_OK):
75+
exit_on_error("Cannot find executable startup script")
76+
77+
def startup(filename):
78+
set_environ()
79+
check_startup(filename)
80+
system(filename)
81+
terminate()
82+
quit()
83+
84+
def run_startup():
85+
filename = "./startup"
86+
check_startup(filename)
87+
t1 = threading.Thread(target = startup, args=(filename,))
88+
t1.start()
89+
90+
def configure_xvnc():
91+
global _number
92+
system("vncconfig -nowin -display=:" + str(_number) + " &")
93+
94+
def change_to_configuration_dir():
95+
global _number
96+
dirname = path.join(environ["HOME"], ".vncdesk", str(_number))
97+
try:
98+
chdir(dirname)
99+
except:
100+
exit_on_error("Cannot access directory " + dirname)
101+
102+
def start(number):
103+
global _number, _display, _xvnc_lock_filename
104+
105+
_number = number
106+
_display = ':' + str(_number)
107+
_xvnc_lock_filename = "/tmp/.X" + str(_number) + "-lock"
108+
109+
change_to_configuration_dir()
110+
read_settings()
111+
create_password()
112+
start_xvnc()
113+
configure_xvnc()
114+
run_startup()

0 commit comments

Comments
 (0)