Example #1
0
    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
Example #2
0
    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)
Example #3
0
    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)
Example #4
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)
Example #5
0
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
Example #6
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)
Example #7
0
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
Example #8
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
Example #9
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
Example #10
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);
Example #11
0
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)
Example #12
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
Example #13
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);