Remmina - The GTK+ Remote Desktop Client  v1.4.33
Remmina is a remote desktop client written in GTK+, aiming to be useful for system administrators and travellers, who need to work with lots of remote computers in front of either large monitors or tiny netbooks. Remmina supports multiple network protocols in an integrated and consistent user interface. Currently RDP, VNC, NX, XDMCP and SSH are supported.
Protocol-Example.md
Go to the documentation of this file.
1 # Example plugin to provide a new protocol
2 
3 
4 
5 ```python
6 import sys
7 import remmina
8 import enum
9 import gi
10 import inspect
11 gi.require_version("Gtk", "3.0")
12 from gi.repository import Gtk, GLib
13 
14 
15 class VncFeature:
16 """
17  Internal data struct to hold ids to feature settings.
18 """
19  PrefQuality = 1
20  PrefViewonly = 2
21  PrefDisableserverinput = 3
22  ToolRefresh = 4
23  ToolChat = 5
24  ToolSendCtrlAltDel = 6
25  Scale = 7
26  Unfocus = 8
27 
28 class VncData:
29 """
30  Internal data struct to hold state.
31 """
32  def __init__(self):
33  self.connected = False
34  self.running = False
35  self.auth_called = False
36  self.auth_first = False
37  self.drawing_area = False
38  self.vnc_buffer = False
39  self.rgb_buffer = False
40 
41 class Plugin:
42 """
43  Plugin implementation
44 """
45 
46  def __init__(self):
47  # This constructor is called before Remmina attempts to register the plugin since it this class has to be instantiated before registering it.
48  self.name = "A short name of the plugin that also appears in the 'Plugin' column in the main dialog."
49  # One of possible values: "pref", "tool", "entry", "protocol" or "secret". This value decides which methods are expected to be defined
50  # in this class.
51  self.type = "protocol"
52  self.description = "VNC but in Python!"
53  self.version = "1.0"
54  self.icon_name = "org.remmina.Remmina-vnc-symbolic"
55  self.icon_name_ssh = "org.remmina.Remmina-vnc-ssh-symbolic"
56  # Specifies which settings are available for this protocol
57  self.ssh_setting = remmina.PROTOCOL_SSH_SETTING_TUNNEL
58 
59  self.gpdata = VncData()
60  self.qualities = ("0", "Poor Pixelmess", "1","Mhh kayy", "2","Nice", "9","hot sh*t")
61  # Define the features this module supports:
62  self.features = [
63  remmina.Feature(
64  type=remmina.PROTOCOL_FEATURE_TYPE_PREF,
65  id=VncFeature.PrefQuality,
66  opt1=remmina.PROTOCOL_FEATURE_PREF_RADIO,
67  opt2="quality",
68  opt3=self.qualities)
69  ,remmina.Feature(remmina.PROTOCOL_FEATURE_TYPE_PREF, VncFeature.PrefViewonly, remmina.PROTOCOL_FEATURE_PREF_CHECK, "viewonly", None)
70  ,remmina.Feature(remmina.PROTOCOL_FEATURE_TYPE_PREF, VncFeature.PrefDisableserverinput, remmina.PROTOCOL_SETTING_TYPE_CHECK, "disableserverinput", "Disable server input")
71  ,remmina.Feature(remmina.PROTOCOL_FEATURE_TYPE_TOOL, VncFeature.ToolRefresh, "Refresh", "face-smile", None)
72  ,remmina.Feature(remmina.PROTOCOL_FEATURE_TYPE_TOOL, VncFeature.ToolChat, "Open Chat…", "face-smile", None)
73  ,remmina.Feature(remmina.PROTOCOL_FEATURE_TYPE_TOOL, VncFeature.ToolSendCtrlAltDel, "Send Ctrl+Alt+Delete", None, None)
74  ,remmina.Feature(remmina.PROTOCOL_FEATURE_TYPE_SCALE, VncFeature.Scale, None, None, None)
75  ,remmina.Feature(remmina.PROTOCOL_FEATURE_TYPE_UNFOCUS, VncFeature.Unfocus, None, None, None)
76  ]
77 
78  colordepths = ("8", "256 colors (8 bpp)", "16", "High color (16 bpp)", "32", "True color (32 bpp)")
79  self.basic_settings = [
80  remmina.Setting(type=remmina.PROTOCOL_SETTING_TYPE_SERVER, name="server", label="", compact=False, opt1="_rfb._tcp",opt2=None)
81  , remmina.Setting(type=remmina.PROTOCOL_SETTING_TYPE_TEXT, name="proxy", label="Repeater", compact=False, opt1=None, opt2=None)
82  , remmina.Setting(type=remmina.PROTOCOL_SETTING_TYPE_TEXT, name="username", label="Username", compact=False, opt1=None, opt2=None)
83  , remmina.Setting(type=remmina.PROTOCOL_SETTING_TYPE_PASSWORD,name="password", label="User password",compact=False, opt1=None, opt2=None)
84  , remmina.Setting(type=remmina.PROTOCOL_SETTING_TYPE_SELECT, name="colordepth",label="Color depth", compact=False, opt1=colordepths,opt2=None)
85  , remmina.Setting(type=remmina.PROTOCOL_SETTING_TYPE_SELECT, name="quality", label="Quality", compact=False, opt1=self.qualities, opt2=None)
86  , remmina.Setting(type=remmina.PROTOCOL_SETTING_TYPE_KEYMAP, name="keymap", label="", compact=False, opt1=None, opt2=None)
87  ]
88  self.advanced_settings = [
89  remmina.Setting(remmina.PROTOCOL_SETTING_TYPE_CHECK, "showcursor", "Show remote cursor", True, None, None)
90  , remmina.Setting(remmina.PROTOCOL_SETTING_TYPE_CHECK, "viewonly", "View only", False, None, None)
91  , remmina.Setting(remmina.PROTOCOL_SETTING_TYPE_CHECK, "disableclipboard", "Disable clipboard sync", True, None, None)
92  , remmina.Setting(remmina.PROTOCOL_SETTING_TYPE_CHECK, "disableencryption", "Disable encryption", False, None, None)
93  , remmina.Setting(remmina.PROTOCOL_SETTING_TYPE_CHECK, "disableserverinput", "Disable server input", True, None, None)
94  , remmina.Setting(remmina.PROTOCOL_SETTING_TYPE_CHECK, "disablepasswordstoring", "Disable password storing", True, None, None)
95  , remmina.Setting(remmina.PROTOCOL_SETTING_TYPE_CHECK, "disablesmoothscrolling", "Disable smooth scrolling", True, None, None)
96  ]
97 
98  def init(self, gp):
99  # this is called when the plugin is loaded from Remmina.
100  cfile = gp.get_file()
101  self.gpdata.disable_smooth_scrolling = cfile.get_setting(key="disablesmoothscrolling", default=False)
102  self.gpdata.drawing_area = gp.get_viewport()
103  return True
104 
105  def open_connection(self, gp):
106  # Is called when the user wants to open a connection whith this plugin.
107 
108  # Write code to initiate the connection. Example:
109  connection_file = gp.get_file()
110  connection_file.set_setting("disablepasswordstoring", False)
111  password = None
112 
113  # Determine if passwords should not be allowed to be stored.
114  dont_save_passwords = connection_file.get_setting("disablepasswordstoring", False)
115  # Open a dialog prompting connection information and credentials
116  ret = remmina.protocol_plugin_init_auth(widget=gp,
117  flags= remmina.REMMINA_MESSAGE_PANEL_FLAG_USERNAME | remmina.REMMINA_MESSAGE_PANEL_FLAG_USERNAME_READONLY | remmina.REMMINA_MESSAGE_PANEL_FLAG_DOMAIN | remmina.REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD,
118  title="Python Rocks!",
119  default_username="",
120  default_password=connection_file.get_setting("password", ""),
121  default_domain="",
122  password_prompt="Your Password Rocks!")
123 
124  # Process the result of the dialog
125  if ret == Gtk.ResponseType.CANCEL:
126  return False
127  elif ret == Gtk.ResponseType.OK:
128  # Indicate that the connection has been established!
129  remmina.protocol_plugin_signal_connection_opened(gp)
130 
131  return True
132 
133  def close_connection(self, gp):
134  # The user requested to close the connection.
135  remmina.protocol_plugin_signal_connection_closed(gp)
136 
137  def query_feature(self, gp, feature):
138  # Remmina asks if the given feature is available (remember Features registered in the construtor).
139  return True
140 
141  def map_event(self, gp):
142  # This is called when the widget is again on screen.
143  return True
144 
145  def unmap_event(self, gp):
146  # This is called when the widget is again not being shown on screen anymore. Any intensive graphical output
147  # can be halted.
148  return True
149 
150  def call_feature(self, gp, feature):
151  # Remmina asks to execute on of the features.
152 
153  if feature.type == remmina.REMMINA_PROTOCOL_FEATURE_TYPE_PREF and feature.id is VncFeature.PrefQuality:
154  file = gp.get_file()
155  quality = file.get_setting("quality", 0)
156  if quality == 9:
157  print("Ramping up graphics. Enjoy!")
158  if quality == 0:
159  print("Squeezing image into a few pixels...")
160  if quality == 1:
161  print("More the average guy, eh?")
162  if quality == 2:
163  print("Not great, not terrible...")
164 
165  def send_keystrokes(self, gp, strokes):
166  # Remmina received a key stroke and wants to pass it to the remote.
167  return True
168 
169  def get_plugin_screenshot(self, gp, data):
170  # data is of type RemminaScreenshotData and should contain the raw pixels for the screenshot. Remmina takes care of storing it into a jpg.
171  # Return True when a screenshot has been done. Otherwise False.
172  return False
173 
174 # Instantiate & Register
175 myPlugin = Plugin()
176 remmina.register_plugin(myPlugin)
177 ```