Coverage for /home/antoine/projects/xpra-git/dist/python3/lib64/python/xpra/server/rfb/rfb_source.py : 94%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2# This file is part of Xpra.
3# Copyright (C) 2017-2018 Antoine Martin <antoine@xpra.org>
4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
5# later version. See the file COPYING for details.
7import struct
8from threading import Event
10from xpra.net.protocol import PACKET_JOIN_SIZE
11from xpra.os_util import memoryview_to_bytes, strtobytes
12from xpra.util import AtomicInteger
13from xpra.log import Logger
15log = Logger("rfb")
17counter = AtomicInteger()
20class RFBSource:
22 def __init__(self, protocol, share=False):
23 self.protocol = protocol
24 self.close_event = Event()
25 self.log_disconnect = True
26 self.ui_client = True
27 self.counter = 0
28 self.share = share
29 self.uuid = "RFB%5i" % counter.increase()
30 self.lock = False
31 self.keyboard_config = None
33 def get_info(self) -> dict:
34 return {
35 "protocol" : "rfb",
36 "uuid" : self.uuid,
37 "share" : self.share,
38 }
40 def get_window_info(self, _wids):
41 return {}
43 def is_closed(self):
44 return self.close_event.isSet()
46 def close(self):
47 self.close_event.set()
49 def ping(self):
50 pass
52 def keys_changed(self):
53 pass
55 def set_default_keymap(self):
56 log("set_default_keymap() keyboard_config=%s", self.keyboard_config)
57 if self.keyboard_config:
58 self.keyboard_config.set_default_keymap()
59 return self.keyboard_config
61 def set_keymap(self, _current_keyboard_config, keys_pressed, _force=False, _translate_only=False):
62 kc = self.keyboard_config
63 kc.keys_pressed = keys_pressed
64 kc.set_keymap(True)
65 kc.owner = self.uuid
67 def send_server_event(self, *_args):
68 pass
70 def send_cursor(self):
71 pass
74 def update_mouse(self, *args):
75 log("update_mouse%s", args)
77 def damage(self, _wid, window, x, y, w, h, options=None):
78 polling = options and options.get("polling", False)
79 p = self.protocol
80 if polling and p is None or p.queue_size()>=2:
81 #very basic RFB update rate control,
82 #if there are packets waiting already
83 #we'll just process the next polling update instead:
84 return
85 img = window.get_image(x, y, w, h)
86 window.acknowledge_changes()
87 log("damage: %s", img)
88 if not img or self.is_closed():
89 return
90 fbupdate = struct.pack(b"!BBH", 0, 0, 1)
91 encoding = 0 #Raw
92 rect = struct.pack(b"!HHHHi", x, y, w, h, encoding)
93 if img.get_rowstride()!=w*4:
94 img.restride(w*4)
95 pixels = img.get_pixels()
96 assert len(pixels)>=4*w*h
97 pixels = pixels[:4*w*h]
98 if len(pixels)<=PACKET_JOIN_SIZE:
99 self.send(fbupdate+rect+memoryview_to_bytes(pixels))
100 else:
101 self.send(fbupdate+rect)
102 self.send(pixels)
104 def send_clipboard(self, text):
105 nocr = strtobytes(text.replace("\r", ""))
106 msg = struct.pack(b"!BBBBI", 3, 0, 0, 0, len(nocr))+nocr
107 self.send(msg)
109 def bell(self, *_args):
110 msg = struct.pack(b"!B", 2)
111 self.send(msg)
113 def send(self, msg):
114 p = self.protocol
115 if p:
116 p.send(msg)