def __init__(self, conn, compression_level): gobject.GObject.__init__(self) self._window_to_id = {} self._id_to_window = {} self._protocol = Protocol(conn, self.process_packet) ClientSource(self._protocol) capabilities_request = dict(default_capabilities) if compression_level: capabilities_request["deflate"] = compression_level root_w, root_h = gtk.gdk.get_default_root_window().get_size() capabilities_request["desktop_size"] = [root_w, root_h] self.send(["hello", capabilities_request]) self._keymap = gtk.gdk.keymap_get_default() self._keymap.connect("keys-changed", self._keys_changed) self._keys_changed() self._xsettings_watcher = None self._root_props_watcher = None # FIXME: these should perhaps be merged. self._clipboard_helper = ClipboardProtocolHelper(self.send) self._client_extras = ClientExtras(self.send) self._focused = None
def init_ui(self, opts): """ initialize user interface """ if not self.readonly: def noauto(v): if not v: return None if str(v).lower() == "auto": return None return v overrides = [ noauto(getattr(opts, "keyboard_%s" % x)) for x in ( "layout", "layouts", "variant", "variants", "options", ) ] def send_keyboard(*parts): self.after_handshake(self.send, *parts) try: self.keyboard_helper = self.keyboard_helper_class( send_keyboard, opts.keyboard_sync, opts.shortcut_modifiers, opts.key_shortcut, opts.keyboard_raw, *overrides) except ImportError as e: keylog("error instantiating %s", self.keyboard_helper_class, exc_info=True) keylog.warn("Warning: no keyboard support, %s", e) if mixin_features.windows: self.init_opengl(opts.opengl) if ClientExtras is not None: self.client_extras = ClientExtras(self, opts) #pylint: disable=not-callable if opts.start or opts.start_child: from xpra.scripts.main import strip_defaults_start_child from xpra.scripts.config import make_defaults_struct defaults = make_defaults_struct() self.start_new_commands = strip_defaults_start_child( opts.start, defaults.start) #pylint: disable=no-member self.start_child_new_commands = strip_defaults_start_child( opts.start_child, defaults.start_child) #pylint: disable=no-member if MOUSE_DELAY_AUTO: try: v = self.get_vrefresh() if v <= 0: #some platforms don't detect the vrefresh correctly #(ie: macos in virtualbox?), so use a sane default: v = 60 self._mouse_position_delay = 1000 // v // 2 log("mouse delay: %s", self._mouse_position_delay) except Exception: log("failed to calculate automatic delay", exc_info=True)
def init_ui(self, opts, extra_args=[]): """ initialize user interface """ if not self.readonly: def noauto(v): if not v: return None if str(v).lower() == "auto": return None return v overrides = [ noauto(getattr(opts, "keyboard_%s" % x)) for x in ("layout", "layouts", "variant", "variants", "options") ] self.keyboard_helper = self.keyboard_helper_class( self.send, opts.keyboard_sync, opts.shortcut_modifiers, opts.key_shortcut, opts.keyboard_raw, *overrides) TrayClient.init_ui(self) NotificationClient.init_ui(self) self.init_opengl(opts.opengl) #audio tagging: AudioClient.init_audio_tagging(self, opts.tray_icon) if ClientExtras is not None: self.client_extras = ClientExtras(self, opts) WindowClient.init_ui(self, opts, extra_args) if MOUSE_DELAY_AUTO: try: from xpra.platform.gui import get_vrefresh v = get_vrefresh() if v <= 0: #some platforms don't detect the vrefresh correctly #(ie: macos in virtualbox?), so use a sane default: v = 60 self._mouse_position_delay = 1000 // v log("mouse delay: %s", self._mouse_position_delay) except Exception: log("failed to calculate automatic delay", exc_info=True)
def __init__(self, conn, opts): XpraClientBase.__init__(self, opts) self.start_time = time.time() self._window_to_id = {} self._id_to_window = {} self.title = opts.title self.readonly = opts.readonly self.session_name = opts.session_name self.compression_level = opts.compression_level self.auto_refresh_delay = opts.auto_refresh_delay self.max_bandwidth = opts.max_bandwidth if self.max_bandwidth > 0.0 and self.jpegquality == 0: """ jpegquality was not set, use a better start value """ self.jpegquality = 50 self.dpi = int(opts.dpi) #statistics: self.server_start_time = -1 self.server_platform = "" self.server_actual_desktop_size = None self.server_randr = False self.pixel_counter = maxdeque(maxlen=100) self.server_latency = maxdeque(maxlen=100) self.server_load = None self.client_latency = maxdeque(maxlen=100) self.last_ping_echoed_time = 0 #features: self.toggle_cursors_bell_notify = False self.toggle_keyboard_sync = False self.window_configure = False self._client_extras = ClientExtras(self, opts) self.client_supports_notifications = opts.notifications and self._client_extras.can_notify( ) self.client_supports_clipboard = opts.clipboard and self._client_extras.supports_clipboard( ) and not self.readonly self.client_supports_cursors = opts.cursors self.client_supports_bell = opts.bell self.notifications_enabled = self.client_supports_notifications self.clipboard_enabled = self.client_supports_clipboard self.cursors_enabled = self.client_supports_cursors self.bell_enabled = self.client_supports_bell #mmap: self.mmap_enabled = False self.mmap = None self.mmap_token = None self.mmap_file = None self.mmap_size = 0 self.supports_mmap = opts.mmap and ( "rgb24" in ENCODINGS) and self._client_extras.supports_mmap() if self.supports_mmap: self.init_mmap(opts.mmap_group, conn.filename) self.init_packet_handlers() self.ready(conn) #keyboard: self.keyboard_sync = opts.keyboard_sync self.key_repeat_delay = -1 self.key_repeat_interval = -1 self.keys_pressed = {} self._remote_version = None self._keymap_changing = False try: self._keymap = gdk.keymap_get_default() except: self._keymap = None self._do_keys_changed() self.key_shortcuts = self.parse_shortcuts(opts.key_shortcuts) self.send_hello() if self._keymap: self._keymap.connect("keys-changed", self._keys_changed) self._focused = None def compute_receive_bandwidth(delay): bytecount = self._protocol.input_bytecount bw = ( (bytecount - self.last_input_bytecount) / 1024) * 1000 / delay self.last_input_bytecount = bytecount log.debug("Bandwidth is ", bw, "kB/s, max ", self.max_bandwidth, "kB/s") q = self.jpegquality if bw > self.max_bandwidth: q -= 10 elif bw < self.max_bandwidth: q += 5 q = max(10, min(95, q)) self.send_jpeg_quality(q) return True if (self.max_bandwidth): self.last_input_bytecount = 0 gobject.timeout_add(2000, compute_receive_bandwidth, 2000) if opts.send_pings: gobject.timeout_add(1000, self.send_ping) else: gobject.timeout_add(20 * 1000, self.send_ping)
class XpraClient(XpraClientBase): __gsignals__ = { "clipboard-toggled": n_arg_signal(0), "keyboard-sync-toggled": n_arg_signal(0), } def __init__(self, conn, opts): XpraClientBase.__init__(self, opts) self.start_time = time.time() self._window_to_id = {} self._id_to_window = {} self.title = opts.title self.readonly = opts.readonly self.session_name = opts.session_name self.compression_level = opts.compression_level self.auto_refresh_delay = opts.auto_refresh_delay self.max_bandwidth = opts.max_bandwidth if self.max_bandwidth > 0.0 and self.jpegquality == 0: """ jpegquality was not set, use a better start value """ self.jpegquality = 50 self.dpi = int(opts.dpi) #statistics: self.server_start_time = -1 self.server_platform = "" self.server_actual_desktop_size = None self.server_randr = False self.pixel_counter = maxdeque(maxlen=100) self.server_latency = maxdeque(maxlen=100) self.server_load = None self.client_latency = maxdeque(maxlen=100) self.last_ping_echoed_time = 0 #features: self.toggle_cursors_bell_notify = False self.toggle_keyboard_sync = False self.window_configure = False self._client_extras = ClientExtras(self, opts) self.client_supports_notifications = opts.notifications and self._client_extras.can_notify( ) self.client_supports_clipboard = opts.clipboard and self._client_extras.supports_clipboard( ) and not self.readonly self.client_supports_cursors = opts.cursors self.client_supports_bell = opts.bell self.notifications_enabled = self.client_supports_notifications self.clipboard_enabled = self.client_supports_clipboard self.cursors_enabled = self.client_supports_cursors self.bell_enabled = self.client_supports_bell #mmap: self.mmap_enabled = False self.mmap = None self.mmap_token = None self.mmap_file = None self.mmap_size = 0 self.supports_mmap = opts.mmap and ( "rgb24" in ENCODINGS) and self._client_extras.supports_mmap() if self.supports_mmap: self.init_mmap(opts.mmap_group, conn.filename) self.init_packet_handlers() self.ready(conn) #keyboard: self.keyboard_sync = opts.keyboard_sync self.key_repeat_delay = -1 self.key_repeat_interval = -1 self.keys_pressed = {} self._remote_version = None self._keymap_changing = False try: self._keymap = gdk.keymap_get_default() except: self._keymap = None self._do_keys_changed() self.key_shortcuts = self.parse_shortcuts(opts.key_shortcuts) self.send_hello() if self._keymap: self._keymap.connect("keys-changed", self._keys_changed) self._focused = None def compute_receive_bandwidth(delay): bytecount = self._protocol.input_bytecount bw = ( (bytecount - self.last_input_bytecount) / 1024) * 1000 / delay self.last_input_bytecount = bytecount log.debug("Bandwidth is ", bw, "kB/s, max ", self.max_bandwidth, "kB/s") q = self.jpegquality if bw > self.max_bandwidth: q -= 10 elif bw < self.max_bandwidth: q += 5 q = max(10, min(95, q)) self.send_jpeg_quality(q) return True if (self.max_bandwidth): self.last_input_bytecount = 0 gobject.timeout_add(2000, compute_receive_bandwidth, 2000) if opts.send_pings: gobject.timeout_add(1000, self.send_ping) else: gobject.timeout_add(20 * 1000, self.send_ping) def init_mmap(self, mmap_group, socket_filename): log("init_mmap(%s, %s)", mmap_group, socket_filename) try: import mmap import tempfile import uuid from stat import S_IRUSR, S_IWUSR, S_IRGRP, S_IWGRP mmap_dir = os.getenv("TMPDIR", "/tmp") if not os.path.exists(mmap_dir): raise Exception("TMPDIR %s does not exist!" % mmap_dir) #create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures #that the file is readable and writable only by the creating user ID temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir) #keep a reference to it so it does not disappear! self._mmap_temp_file = temp self.mmap_file = temp.name fd = temp.file.fileno() #set the group permissions and gid if the mmap-group option is specified if mmap_group and type(socket_filename) == str and os.path.exists( socket_filename): s = os.stat(socket_filename) os.fchown(fd, -1, s.st_gid) os.fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) self.mmap_size = max(4096, mmap.PAGESIZE) * 32 * 1024 #generally 128MB log("using mmap file %s, fd=%s, size=%s", self.mmap_file, fd, self.mmap_size) os.lseek(fd, self.mmap_size - 1, os.SEEK_SET) assert os.write(fd, '\x00') os.lseek(fd, 0, os.SEEK_SET) self.mmap = mmap.mmap(fd, length=self.mmap_size) #write the 16 byte token one byte at a time - no endianness self.mmap_token = uuid.uuid4().int log.debug("mmap_token=%s", self.mmap_token) v = self.mmap_token for i in range(0, 16): poke = ctypes.c_ubyte.from_buffer(self.mmap, 512 + i) poke.value = v % 256 v = v >> 8 assert v == 0 except Exception, e: log.error("failed to setup mmap: %s", e) self.supports_mmap = False self.clean_mmap() self.mmap = None self.mmap_file = None self.mmap_size = 0
def __init__(self, conn, opts): XpraClientBase.__init__(self, opts) self.start_time = time.time() self._window_to_id = {} self._id_to_window = {} self._ui_events = 0 self.title = opts.title self.readonly = opts.readonly self.session_name = opts.session_name self.compression_level = opts.compression_level self.auto_refresh_delay = opts.auto_refresh_delay self.max_bandwidth = opts.max_bandwidth if self.max_bandwidth>0.0 and self.jpegquality==0: """ jpegquality was not set, use a better start value """ self.jpegquality = 50 self.dpi = int(opts.dpi) #statistics: self.server_start_time = -1 self.server_platform = "" self.server_actual_desktop_size = None self.server_randr = False self.pixel_counter = maxdeque(maxlen=100) self.server_latency = maxdeque(maxlen=100) self.server_load = None self.client_latency = maxdeque(maxlen=100) self.last_ping_echoed_time = 0 #features: self.toggle_cursors_bell_notify = False self.toggle_keyboard_sync = False self.window_configure = False self._client_extras = ClientExtras(self, opts) self.client_supports_notifications = opts.notifications and self._client_extras.can_notify() self.client_supports_clipboard = opts.clipboard and self._client_extras.supports_clipboard() and not self.readonly self.client_supports_cursors = opts.cursors self.client_supports_bell = opts.bell self.client_supports_sharing = opts.sharing self.notifications_enabled = self.client_supports_notifications self.clipboard_enabled = self.client_supports_clipboard self.cursors_enabled = self.client_supports_cursors self.bell_enabled = self.client_supports_bell #mmap: self.mmap_enabled = False self.mmap = None self.mmap_token = None self.mmap_file = None self.mmap_size = 0 self.supports_mmap = opts.mmap and ("rgb24" in ENCODINGS) and self._client_extras.supports_mmap() if self.supports_mmap: self.init_mmap(opts.mmap_group, conn.filename) self.init_packet_handlers() self.ready(conn) #keyboard: self.keyboard_sync = opts.keyboard_sync self.key_repeat_delay = -1 self.key_repeat_interval = -1 self.keys_pressed = {} self._remote_version = None self._keymap_changing = False try: self._keymap = gdk.keymap_get_default() except: self._keymap = None self._do_keys_changed() self.key_shortcuts = self.parse_shortcuts(opts.key_shortcuts) log.info("xpra client version %s" % __version__) self.send_hello() if self._keymap: self._keymap.connect("keys-changed", self._keys_changed) self._focused = None def compute_receive_bandwidth(delay): bytecount = self._protocol.input_bytecount bw = ((bytecount - self.last_input_bytecount) / 1024) * 1000 / delay self.last_input_bytecount = bytecount; log.debug("Bandwidth is ", bw, "kB/s, max ", self.max_bandwidth, "kB/s") q = self.jpegquality if bw > self.max_bandwidth: q -= 10 elif bw < self.max_bandwidth: q += 5 q = max(10, min(95 ,q)) self.send_jpeg_quality(q) return True if (self.max_bandwidth): self.last_input_bytecount = 0 gobject.timeout_add(2000, compute_receive_bandwidth, 2000) if opts.send_pings: gobject.timeout_add(1000, self.send_ping) else: gobject.timeout_add(20*1000, self.send_ping)
class XpraClient(XpraClientBase): __gsignals__ = { "clipboard-toggled": n_arg_signal(0), "keyboard-sync-toggled": n_arg_signal(0), } def __init__(self, conn, opts): XpraClientBase.__init__(self, opts) self.start_time = time.time() self._window_to_id = {} self._id_to_window = {} self._ui_events = 0 self.title = opts.title self.readonly = opts.readonly self.session_name = opts.session_name self.compression_level = opts.compression_level self.auto_refresh_delay = opts.auto_refresh_delay self.max_bandwidth = opts.max_bandwidth if self.max_bandwidth>0.0 and self.jpegquality==0: """ jpegquality was not set, use a better start value """ self.jpegquality = 50 self.dpi = int(opts.dpi) #statistics: self.server_start_time = -1 self.server_platform = "" self.server_actual_desktop_size = None self.server_randr = False self.pixel_counter = maxdeque(maxlen=100) self.server_latency = maxdeque(maxlen=100) self.server_load = None self.client_latency = maxdeque(maxlen=100) self.last_ping_echoed_time = 0 #features: self.toggle_cursors_bell_notify = False self.toggle_keyboard_sync = False self.window_configure = False self._client_extras = ClientExtras(self, opts) self.client_supports_notifications = opts.notifications and self._client_extras.can_notify() self.client_supports_clipboard = opts.clipboard and self._client_extras.supports_clipboard() and not self.readonly self.client_supports_cursors = opts.cursors self.client_supports_bell = opts.bell self.client_supports_sharing = opts.sharing self.notifications_enabled = self.client_supports_notifications self.clipboard_enabled = self.client_supports_clipboard self.cursors_enabled = self.client_supports_cursors self.bell_enabled = self.client_supports_bell #mmap: self.mmap_enabled = False self.mmap = None self.mmap_token = None self.mmap_file = None self.mmap_size = 0 self.supports_mmap = opts.mmap and ("rgb24" in ENCODINGS) and self._client_extras.supports_mmap() if self.supports_mmap: self.init_mmap(opts.mmap_group, conn.filename) self.init_packet_handlers() self.ready(conn) #keyboard: self.keyboard_sync = opts.keyboard_sync self.key_repeat_delay = -1 self.key_repeat_interval = -1 self.keys_pressed = {} self._remote_version = None self._keymap_changing = False try: self._keymap = gdk.keymap_get_default() except: self._keymap = None self._do_keys_changed() self.key_shortcuts = self.parse_shortcuts(opts.key_shortcuts) log.info("xpra client version %s" % __version__) self.send_hello() if self._keymap: self._keymap.connect("keys-changed", self._keys_changed) self._focused = None def compute_receive_bandwidth(delay): bytecount = self._protocol.input_bytecount bw = ((bytecount - self.last_input_bytecount) / 1024) * 1000 / delay self.last_input_bytecount = bytecount; log.debug("Bandwidth is ", bw, "kB/s, max ", self.max_bandwidth, "kB/s") q = self.jpegquality if bw > self.max_bandwidth: q -= 10 elif bw < self.max_bandwidth: q += 5 q = max(10, min(95 ,q)) self.send_jpeg_quality(q) return True if (self.max_bandwidth): self.last_input_bytecount = 0 gobject.timeout_add(2000, compute_receive_bandwidth, 2000) if opts.send_pings: gobject.timeout_add(1000, self.send_ping) else: gobject.timeout_add(20*1000, self.send_ping) def init_mmap(self, mmap_group, socket_filename): log("init_mmap(%s, %s)", mmap_group, socket_filename) try: import mmap import tempfile import uuid from stat import S_IRUSR,S_IWUSR,S_IRGRP,S_IWGRP mmap_dir = os.getenv("TMPDIR", "/tmp") if not os.path.exists(mmap_dir): raise Exception("TMPDIR %s does not exist!" % mmap_dir) #create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures #that the file is readable and writable only by the creating user ID temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir) #keep a reference to it so it does not disappear! self._mmap_temp_file = temp self.mmap_file = temp.name fd = temp.file.fileno() #set the group permissions and gid if the mmap-group option is specified if mmap_group and type(socket_filename)==str and os.path.exists(socket_filename): s = os.stat(socket_filename) os.fchown(fd, -1, s.st_gid) os.fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) self.mmap_size = max(4096, mmap.PAGESIZE)*32*1024 #generally 128MB log("using mmap file %s, fd=%s, size=%s", self.mmap_file, fd, self.mmap_size) os.lseek(fd, self.mmap_size-1, os.SEEK_SET) assert os.write(fd, '\x00') os.lseek(fd, 0, os.SEEK_SET) self.mmap = mmap.mmap(fd, length=self.mmap_size) #write the 16 byte token one byte at a time - no endianness self.mmap_token = uuid.uuid4().int log.debug("mmap_token=%s", self.mmap_token) v = self.mmap_token for i in range(0,16): poke = ctypes.c_ubyte.from_buffer(self.mmap, 512+i) poke.value = v % 256 v = v>>8 assert v==0 except Exception, e: log.error("failed to setup mmap: %s", e) self.supports_mmap = False self.clean_mmap() self.mmap = None self.mmap_file = None self.mmap_size = 0
def __init__(self, conn, opts): XpraClientBase.__init__(self, opts) self.start_time = time.time() self._window_to_id = {} self._id_to_window = {} title = opts.title if opts.title_suffix is not None: title = "@title@ %s" % opts.title_suffix self.title = title self.readonly = opts.readonly self.session_name = opts.session_name self.compression_level = opts.compression_level self.auto_refresh_delay = opts.auto_refresh_delay self.max_bandwidth = opts.max_bandwidth if self.max_bandwidth>0.0 and self.jpegquality==0: """ jpegquality was not set, use a better start value """ self.jpegquality = 50 self.server_capabilities = {} self.mmap_enabled = False self.server_start_time = -1 self.server_platform = "" self.server_actual_desktop_size = None self.server_desktop_size = None self.server_randr = False self.pixel_counter = maxdeque(maxlen=100) self.server_latency = maxdeque(maxlen=100) self.server_load = None self.client_latency = maxdeque(maxlen=100) self.toggle_cursors_bell_notify = False self.bell_enabled = True self.cursors_enabled = True self.notifications_enabled = True self.clipboard_enabled = False self.mmap = None self.mmap_token = None self.mmap_file = None self.mmap_size = 0 self._client_extras = ClientExtras(self, opts) self.clipboard_enabled = not self.readonly and opts.clipboard and self._client_extras.supports_clipboard() self.supports_mmap = opts.mmap and ("rgb24" in ENCODINGS) and self._client_extras.supports_mmap() if self.supports_mmap: try: import mmap import tempfile import uuid from stat import S_IRUSR,S_IWUSR,S_IRGRP,S_IWGRP mmap_dir = os.getenv("TMPDIR", "/tmp") if not os.path.exists(mmap_dir): raise Exception("TMPDIR %s does not exist!" % mmap_dir) #create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures #that the file is readable and writable only by the creating user ID temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir) #keep a reference to it so it does not disappear! self._mmap_temp_file = temp self.mmap_file = temp.name fd = temp.file.fileno() #set the group permissions and gid if the mmap-group option is specified if opts.mmap_group and type(conn.target)==str and os.path.exists(conn.target): s = os.stat(conn.target) os.fchown(fd, -1, s.st_gid) os.fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) self.mmap_size = max(4096, mmap.PAGESIZE)*32*1024 #generally 128MB log("using mmap file %s, fd=%s, size=%s", self.mmap_file, fd, self.mmap_size) os.lseek(fd, self.mmap_size-1, os.SEEK_SET) assert os.write(fd, '\x00') os.lseek(fd, 0, os.SEEK_SET) self.mmap = mmap.mmap(fd, length=self.mmap_size) #write the 16 byte token one byte at a time - no endianness self.mmap_token = uuid.uuid4().int log.debug("mmap_token=%s", self.mmap_token) v = self.mmap_token for i in range(0,16): poke = ctypes.c_ubyte.from_buffer(self.mmap, 512+i) poke.value = v % 256 v = v>>8 assert v==0 except Exception, e: log.error("failed to setup mmap: %s", e) self.supports_mmap = False self.clean_mmap() self.mmap = None self.mmap_file = None self.mmap_size = 0
def __init__(self, conn, opts): XpraClientBase.__init__(self, opts) self.start_time = time.time() self._window_to_id = {} self._id_to_window = {} self.title = opts.title self.readonly = opts.readonly self.session_name = opts.session_name self.compression_level = opts.compression_level self.auto_refresh_delay = opts.auto_refresh_delay self.max_bandwidth = opts.max_bandwidth if self.max_bandwidth > 0.0 and self.jpegquality == 0: """ jpegquality was not set, use a better start value """ self.jpegquality = 50 self.mmap_enabled = False self.server_start_time = -1 self.server_platform = "" self.server_actual_desktop_size = None self.server_randr = False self.pixel_counter = maxdeque(maxlen=100) self.server_latency = maxdeque(maxlen=100) self.server_load = None self.client_latency = maxdeque(maxlen=100) self.toggle_cursors_bell_notify = False self.toggle_keyboard_sync = False self.bell_enabled = True self.cursors_enabled = True self.notifications_enabled = True self.clipboard_enabled = False self.window_configure = False self.mmap = None self.mmap_token = None self.mmap_file = None self.mmap_size = 0 self.last_ping_echoed_time = 0 self._client_extras = ClientExtras(self, opts) self.clipboard_enabled = not self.readonly and opts.clipboard and self._client_extras.supports_clipboard( ) self.supports_mmap = opts.mmap and ( "rgb24" in ENCODINGS) and self._client_extras.supports_mmap() if self.supports_mmap: try: import mmap import tempfile import uuid from stat import S_IRUSR, S_IWUSR, S_IRGRP, S_IWGRP mmap_dir = os.getenv("TMPDIR", "/tmp") if not os.path.exists(mmap_dir): raise Exception("TMPDIR %s does not exist!" % mmap_dir) #create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures #that the file is readable and writable only by the creating user ID temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir) #keep a reference to it so it does not disappear! self._mmap_temp_file = temp self.mmap_file = temp.name fd = temp.file.fileno() #set the group permissions and gid if the mmap-group option is specified if opts.mmap_group and type( conn.target) == str and os.path.exists(conn.target): s = os.stat(conn.target) os.fchown(fd, -1, s.st_gid) os.fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) self.mmap_size = max( 4096, mmap.PAGESIZE) * 32 * 1024 #generally 128MB log("using mmap file %s, fd=%s, size=%s", self.mmap_file, fd, self.mmap_size) os.lseek(fd, self.mmap_size - 1, os.SEEK_SET) assert os.write(fd, '\x00') os.lseek(fd, 0, os.SEEK_SET) self.mmap = mmap.mmap(fd, length=self.mmap_size) #write the 16 byte token one byte at a time - no endianness self.mmap_token = uuid.uuid4().int log.debug("mmap_token=%s", self.mmap_token) v = self.mmap_token for i in range(0, 16): poke = ctypes.c_ubyte.from_buffer(self.mmap, 512 + i) poke.value = v % 256 v = v >> 8 assert v == 0 except Exception, e: log.error("failed to setup mmap: %s", e) self.supports_mmap = False self.clean_mmap() self.mmap = None self.mmap_file = None self.mmap_size = 0
class XpraClient(XpraClientBase): __gsignals__ = { "clipboard-toggled": n_arg_signal(0), } def __init__(self, conn, opts): XpraClientBase.__init__(self, opts) self.start_time = time.time() self._window_to_id = {} self._id_to_window = {} title = opts.title if opts.title_suffix is not None: title = "@title@ %s" % opts.title_suffix self.title = title self.readonly = opts.readonly self.session_name = opts.session_name self.compression_level = opts.compression_level self.auto_refresh_delay = opts.auto_refresh_delay self.max_bandwidth = opts.max_bandwidth if self.max_bandwidth>0.0 and self.jpegquality==0: """ jpegquality was not set, use a better start value """ self.jpegquality = 50 self.server_capabilities = {} self.can_ping = False self.mmap_enabled = False self.server_start_time = -1 self.server_platform = "" self.server_actual_desktop_size = None self.server_desktop_size = None self.server_randr = False self.pixel_counter = deque(maxlen=100) self.server_latency = deque(maxlen=100) self.server_load = None self.client_latency = deque(maxlen=100) self.bell_enabled = True self.notifications_enabled = True self.send_damage_sequence = False self.clipboard_enabled = False self.mmap = None self.mmap_token = None self.mmap_file = None self.mmap_size = 0 self._client_extras = ClientExtras(self, opts) self.clipboard_enabled = not self.readonly and opts.clipboard and self._client_extras.supports_clipboard() self.supports_mmap = opts.mmap and self._client_extras.supports_mmap() if self.supports_mmap: try: import mmap import tempfile import uuid import ctypes from stat import S_IRUSR,S_IWUSR mmap_dir = os.getenv("TMPDIR", "/tmp") if not os.path.exists(mmap_dir): raise Exception("TMPDIR %s does not exist!" % mmap_dir) temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir) #keep a reference to it so it does not disappear! self._mmap_temp_file = temp self.mmap_file = temp.name #ensure that the permissions are strict: os.chmod(self.mmap_file, S_IRUSR|S_IWUSR) self.mmap_size = max(4096, mmap.PAGESIZE)*32*1024 #generally 128MB fd = temp.file.fileno() log("using mmap file %s, fd=%s, size=%s", self.mmap_file, fd, self.mmap_size) os.lseek(fd, self.mmap_size-1, os.SEEK_SET) assert os.write(fd, '\x00') os.lseek(fd, 0, os.SEEK_SET) self.mmap = mmap.mmap(fd, length=self.mmap_size) #write the 16 byte token one byte at a time - no endianness self.mmap_token = uuid.uuid4().int log.debug("mmap_token=%s", self.mmap_token) v = self.mmap_token for i in range(0,16): poke = ctypes.c_ubyte.from_buffer(self.mmap, 512+i) poke.value = v % 256 v = v>>8 assert v==0 except Exception, e: log.error("failed to setup mmap: %s", e) self.supports_mmap = False self.clean_mmap() self.mmap = None self.mmap_file = None self.mmap_size = 0 self.init_packet_handlers() self.ready(conn) self.keyboard_sync = opts.keyboard_sync self.key_repeat_modifiers = False self.key_repeat_delay = -1 self.key_repeat_interval = -1 self.keys_pressed = {} self.send_nuisance_modifiers = False self.keyboard_as_properties = False self._raw_keycodes_feature = False self._raw_keycodes_full = False self._focus_modifiers_feature = False self._remote_version = None self._keymap_changing = False self._keymap = gtk.gdk.keymap_get_default() self._do_keys_changed() self.key_shortcuts = self.parse_shortcuts(opts.key_shortcuts) self.send_hello() self._keymap.connect("keys-changed", self._keys_changed) self._xsettings_watcher = None self._root_props_watcher = None self._focused = None def compute_receive_bandwidth(delay): bw = (self._protocol._recv_counter / 1024) * 1000/ delay; self._protocol._recv_counter = 0; log.debug("Bandwidth is ", bw, "kB/s, max ", self.max_bandwidth, "kB/s") q = self.jpegquality if bw > self.max_bandwidth: q -= 10 elif bw < self.max_bandwidth: q += 5 q = max(10, min(95 ,q)) self.send_jpeg_quality(q) return True if (self.max_bandwidth): gobject.timeout_add(2000, compute_receive_bandwidth, 2000);
class XpraClient(gobject.GObject): __gsignals__ = { "handshake-complete": n_arg_signal(0), "received-gibberish": n_arg_signal(1), } def __init__(self, conn, compression_level): gobject.GObject.__init__(self) self._window_to_id = {} self._id_to_window = {} self._protocol = Protocol(conn, self.process_packet) ClientSource(self._protocol) capabilities_request = dict(default_capabilities) if compression_level: capabilities_request["deflate"] = compression_level root_w, root_h = gtk.gdk.get_default_root_window().get_size() capabilities_request["desktop_size"] = [root_w, root_h] self.send(["hello", capabilities_request]) self._keymap = gtk.gdk.keymap_get_default() self._keymap.connect("keys-changed", self._keys_changed) self._keys_changed() self._xsettings_watcher = None self._root_props_watcher = None # FIXME: these should perhaps be merged. self._clipboard_helper = ClipboardProtocolHelper(self.send) self._client_extras = ClientExtras(self.send) self._focused = None def run(self): gtk_main_quit_on_fatal_exceptions_enable() gtk.main() def _keys_changed(self, *args): self._modifier_map = grok_modifier_map(gtk.gdk.display_get_default()) def update_focus(self, id, gotit): if gotit and self._focused is not id: self.send(["focus", id]) self._focused = id if not gotit and self._focused is id: self.send(["focus", 0]) self._focused = None def mask_to_names(self, mask): return mask_to_names(mask, self._modifier_map) def send(self, packet): self._protocol.source.queue_ordinary_packet(packet) def send_positional(self, packet): self._protocol.source.queue_positional_packet(packet) def send_mouse_position(self, packet): self._protocol.source.queue_mouse_position_packet(packet) def _process_hello(self, packet): (_, capabilities) = packet if "deflate" in capabilities: self._protocol.enable_deflate(capabilities["deflate"]) if capabilities.get("__prerelease_version") != xpra.__version__: log.error("sorry, I only know how to talk to v%s servers", xpra.__version__) gtk.main_quit() return if "desktop_size" in capabilities: avail_w, avail_h = capabilities["desktop_size"] root_w, root_h = gtk.gdk.get_default_root_window().get_size() if (avail_w, avail_h) < (root_w, root_h): log.warn("Server's virtual screen is too small -- " "(server: %sx%s vs. client: %sx%s)\n" "You may see strange behavior.\n" "Please complain to " "*****@*****.**" % (avail_w, avail_h, root_w, root_h)) self._clipboard_helper.send_all_tokens() self._client_extras.handshake_complete(capabilities) self.emit("handshake-complete") def _process_new_common(self, packet, override_redirect): (_, id, x, y, w, h, metadata) = packet window = ClientWindow(self, id, x, y, w, h, metadata, override_redirect) self._id_to_window[id] = window self._window_to_id[window] = id window.show_all() def _process_new_window(self, packet): self._process_new_common(packet, False) def _process_new_override_redirect(self, packet): self._process_new_common(packet, True) def _process_draw(self, packet): (_, id, x, y, width, height, coding, data) = packet window = self._id_to_window[id] assert coding == "rgb24" window.draw(x, y, width, height, data) def _process_window_metadata(self, packet): (_, id, metadata) = packet window = self._id_to_window[id] window.update_metadata(metadata) def _process_configure_override_redirect(self, packet): (_, id, x, y, w, h) = packet window = self._id_to_window[id] window.move_resize(x, y, w, h) def _process_lost_window(self, packet): (_, id) = packet window = self._id_to_window[id] del self._id_to_window[id] del self._window_to_id[window] window.destroy() def _process_connection_lost(self, packet): log.error("Connection lost") gtk_main_quit_really() def _process_gibberish(self, packet): [_, data] = packet self.emit("received-gibberish", data) _packet_handlers = { "hello": _process_hello, "new-window": _process_new_window, "new-override-redirect": _process_new_override_redirect, "draw": _process_draw, "window-metadata": _process_window_metadata, "configure-override-redirect": _process_configure_override_redirect, "lost-window": _process_lost_window, # "clipboard-*" packets are handled by a special case below. Protocol.CONNECTION_LOST: _process_connection_lost, Protocol.GIBBERISH: _process_gibberish, } def process_packet(self, proto, packet): packet_type = packet[0] if (isinstance(packet_type, str) and packet_type.startswith("clipboard-")): self._clipboard_helper.process_clipboard_packet(packet) else: self._packet_handlers[packet_type](self, packet)
def __init__(self, conn, opts): XpraClientBase.__init__(self, opts) self.start_time = time.time() self._window_to_id = {} self._id_to_window = {} title = opts.title if opts.title_suffix is not None: title = "@title@ %s" % opts.title_suffix self.title = title self.readonly = opts.readonly self.session_name = opts.session_name self.compression_level = opts.compression_level self.auto_refresh_delay = opts.auto_refresh_delay self.max_bandwidth = opts.max_bandwidth if self.max_bandwidth>0.0 and self.jpegquality==0: """ jpegquality was not set, use a better start value """ self.jpegquality = 50 self.server_capabilities = {} self.can_ping = False self.mmap_enabled = False self.server_start_time = -1 self.server_platform = "" self.server_actual_desktop_size = None self.server_desktop_size = None self.server_randr = False self.pixel_counter = deque(maxlen=100) self.server_latency = deque(maxlen=100) self.server_load = None self.client_latency = deque(maxlen=100) self.bell_enabled = True self.notifications_enabled = True self.send_damage_sequence = False self.clipboard_enabled = False self.mmap = None self.mmap_token = None self.mmap_file = None self.mmap_size = 0 self._client_extras = ClientExtras(self, opts) self.clipboard_enabled = not self.readonly and opts.clipboard and self._client_extras.supports_clipboard() self.supports_mmap = opts.mmap and self._client_extras.supports_mmap() if self.supports_mmap: try: import mmap import tempfile import uuid import ctypes from stat import S_IRUSR,S_IWUSR mmap_dir = os.getenv("TMPDIR", "/tmp") if not os.path.exists(mmap_dir): raise Exception("TMPDIR %s does not exist!" % mmap_dir) temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir) #keep a reference to it so it does not disappear! self._mmap_temp_file = temp self.mmap_file = temp.name #ensure that the permissions are strict: os.chmod(self.mmap_file, S_IRUSR|S_IWUSR) self.mmap_size = max(4096, mmap.PAGESIZE)*32*1024 #generally 128MB fd = temp.file.fileno() log("using mmap file %s, fd=%s, size=%s", self.mmap_file, fd, self.mmap_size) os.lseek(fd, self.mmap_size-1, os.SEEK_SET) assert os.write(fd, '\x00') os.lseek(fd, 0, os.SEEK_SET) self.mmap = mmap.mmap(fd, length=self.mmap_size) #write the 16 byte token one byte at a time - no endianness self.mmap_token = uuid.uuid4().int log.debug("mmap_token=%s", self.mmap_token) v = self.mmap_token for i in range(0,16): poke = ctypes.c_ubyte.from_buffer(self.mmap, 512+i) poke.value = v % 256 v = v>>8 assert v==0 except Exception, e: log.error("failed to setup mmap: %s", e) self.supports_mmap = False self.clean_mmap() self.mmap = None self.mmap_file = None self.mmap_size = 0