Exemple #1
0
 def init_video_decoder_option(self, decoder_name):
     decoder_module = get_codec(decoder_name)
     log("init_video_decoder_option(%s)", decoder_name)
     log(" module=%s", decoder_module)
     if not decoder_module:
         log(" video decoder %s could not be loaded:", decoder_name)
         log(" %s", get_codec_error(decoder_name))
         return
     decoder_type = decoder_module.get_type()
     try:
         decoder_module.init_module()
         self._cleanup_modules.append(decoder_module)
     except Exception as e:
         log("exception in %s module initialization %s: %s", decoder_type, decoder_module.init_module, e, exc_info=True)
         log.warn("Warning: cannot use %s module %s: %s", decoder_type, decoder_module, e, exc_info=True)
         return
     encodings = decoder_module.get_encodings()
     log(" %s encodings=%s", decoder_type, csv(encodings))
     for encoding in encodings:
         colorspaces = decoder_module.get_input_colorspaces(encoding)
         log(" %s input colorspaces for %s: %s", decoder_type, encoding, csv(colorspaces))
         for colorspace in colorspaces:
             output_colorspace = decoder_module.get_output_colorspace(encoding, colorspace)
             log(" %s output colorspace for %s/%s: %s", decoder_type, encoding, colorspace, output_colorspace)
             try:
                 assert decoder_module.Decoder
                 self.add_decoder(encoding, colorspace, decoder_name, decoder_module)
             except Exception as e:
                 log.warn("failed to add decoder %s: %s", decoder_module, e)
Exemple #2
0
 def run(self, *args):
     if len(args)==1 and args[0]=="status":
         from xpra.log import get_all_loggers
         return "logging is enabled for: %s" % str(list([str(x) for x in get_all_loggers() if x.is_debug_enabled()]))
     if len(args)<2:
         self.raise_error("not enough arguments")
     log_cmd = args[0]
     if log_cmd not in ("enable", "disable"):
         self.raise_error("only 'enable' and 'disable' verbs are supported")
     #support both separate arguments and csv:
     categories = []
     for x in args[1:]:
         categories += [v.strip() for v in x.split(",")]
     from xpra.log import add_debug_category, add_disabled_category, enable_debug_for, disable_debug_for
     if log_cmd=="enable":
         add_debug_category(*categories)
         loggers = enable_debug_for(*categories)
     else:
         assert log_cmd=="disable"
         add_disabled_category(*categories)
         loggers = disable_debug_for(*categories)
     if not loggers:
         log.info("no loggers matching: %s", csv(categories))
     else:
         log.info("%sd debugging for: %s", log_cmd, csv(loggers))
     return "logging %sd for %s" % (log_cmd, csv(loggers))
Exemple #3
0
 def select_clipboard_menu_option(self, item=None, label=None, labels=[]):
     #ensure that only the matching menu item is selected,
     #(can be specified as a menuitem object, or using its label)
     #all the other menu items whose labels are specified will be made inactive
     #(we use a flag to prevent reentry)
     clipboardlog("select_clipboard_menu_option(%s, %s, %s) clipboard_change_pending=%s", item, label, labels, self._clipboard_change_pending)
     if self._clipboard_change_pending:
         return None
     clipboard = self.get_menu("Clipboard")
     if not clipboard:
         log.error("Error: cannot locate Clipboard menu object!")
         return None
     all_items = [x for x in clipboard.get_submenu().get_children() if x.get_label() in labels]
     selected_items = [x for x in all_items if x==item] + [x for x in all_items if x.get_label()==label]
     if not selected_items:
         log.error("Error: cannot find any clipboard menu options to match '%s'", label)
         log.error(" all menu items: %s", csv(all_items))
         log.error(" selected: %s", csv(selected_items))
         return None
     self._clipboard_change_pending = True
     sel = selected_items[0]
     if not label:
         label = sel.get_label()
     for x in all_items:
         active = x.get_label()==label
         if x.get_active()!=active:
             x.set_active(active)
     self._clipboard_change_pending = False
     return label
Exemple #4
0
 def _print_file(self, filename, mimetype, options):
     printer = options.strget("printer")
     title   = options.strget("title")
     copies  = options.intget("copies", 1)
     if title:
         printlog.info(" sending '%s' to printer '%s'", title, printer)
     else:
         printlog.info(" sending to printer '%s'", printer)
     from xpra.platform.printing import print_files, printing_finished, get_printers
     printers = get_printers()
     def delfile():
         if not DELETE_PRINTER_FILE:
             return
         try:
             os.unlink(filename)
         except:
             printlog("failed to delete print job file '%s'", filename)
         return False
     if not printer:
         printlog.error("Error: the printer name is missing")
         printlog.error(" printers available: %s", csv(printers.keys()) or "none")
         delfile()
         return
     if printer not in printers:
         printlog.error("Error: printer '%s' does not exist!", printer)
         printlog.error(" printers available: %s", csv(printers.keys()) or "none")
         delfile()
         return
     try:
         job_options = options.get("options")
         job_options["copies"] = copies
         job = print_files(printer, [filename], title, job_options)
     except Exception as e:
         printlog("print_files%s", (printer, [filename], title, options), exc_info=True)
         printlog.error("Error: cannot print file '%s'", os.path.basename(filename))
         printlog.error(" %s", e)
         delfile()
         return
     printlog("printing %s, job=%s", filename, job)
     if job<=0:
         printlog("printing failed and returned %i", job)
         delfile()
         return
     start = time.time()
     def check_printing_finished():
         done = printing_finished(job)
         printlog("printing_finished(%s)=%s", job, done)
         if done:
             delfile()
             return False
         if time.time()-start>10*60:
             printlog.warn("print job %s timed out", job)
             delfile()
             return False
         return True #try again..
     if check_printing_finished():
         self.timeout_add(10000, check_printing_finished)
Exemple #5
0
 def set_modules(self, video_encoders=[], csc_modules=[], video_decoders=[]):
     assert not self._initialized, "too late to set modules, the helper is already initialized!"
     def filt(name, inlist, all_list):
         notfound = [x for x in inlist if x and x not in all_list]
         if notfound:
             log.warn("ignoring unknown %s: %s", name, ", ".join(notfound))
         return [x for x in inlist if x in all_list]
     self.video_encoders = filt("video encoders" , video_encoders,   ALL_VIDEO_ENCODER_OPTIONS)
     self.csc_modules    = filt("csc modules"    , csc_modules,      ALL_CSC_MODULE_OPTIONS)
     self.video_decoders = filt("video decoders" , video_decoders,   ALL_VIDEO_DECODER_OPTIONS)
     log("VideoHelper.set_modules(%s, %s, %s) video encoders=%s, csc=%s, video decoders=%s",
         csv(video_encoders), csv(csc_modules), csv(video_decoders), csv(self.video_encoders), csv(self.csc_modules), csv(self.video_decoders))
Exemple #6
0
 def init_csc_options(self):
     log("init_csc_options()")
     log(" will try csc modules: %s", csv(self.csc_modules))
     for x in self.csc_modules:
         try:
             mod = get_csc_module_name(x)
             self.init_csc_option(mod)
         except:
             log.warn("init_csc_options() cannot add %s csc", x, exc_info=True)
     log(" csc specs: %s", csv(self._csc_encoder_specs))
     for src_format, d in sorted(self._csc_encoder_specs.items()):
         log(" %s - %s options:", src_format, len(d))
         for dst_format, specs in sorted(d.items()):
             log("  * %s via: %s", dst_format, csv(sorted(spec.codec_type for spec in specs)))
Exemple #7
0
def main():
    global pygst_version, gst_version, gst_vinfo
    from xpra.platform import program_context
    from xpra.log import enable_color
    with program_context("GStreamer-Info", "GStreamer Information"):
        enable_color()
        if "-v" in sys.argv or "--verbose" in sys.argv:
            log.enable_debug()
        import_gst()
        print("Loaded Python GStreamer version %s for Python %s.%s" % (gst_vinfo, sys.version_info[0], sys.version_info[1]))
        apn = get_all_plugin_names()
        print("GStreamer plugins found: %s" % csv(apn))
        print("")
        print("GStreamer version: %s" % ".".join([str(x) for x in gst_version]))
        print("PyGStreamer version: %s" % ".".join([str(x) for x in pygst_version]))
        print("")
        encs = [x for x in CODEC_ORDER if has_encoder(x)]
        decs = [x for x in CODEC_ORDER if has_decoder(x)]
        print("encoders:           %s" % csv(encs))
        print("decoders:           %s" % csv(decs))
        print("muxers:             %s" % csv(get_muxers()))
        print("demuxers:           %s" % csv(get_demuxers()))
        print("stream compressors: %s" % csv(get_stream_compressors()))
        print("source plugins:     %s" % csv([x for x in get_source_plugins() if x in apn]))
        print("sink plugins:       %s" % csv([x for x in get_sink_plugins() if x in apn]))
        print("default sink:       %s" % get_default_sink())
Exemple #8
0
 def filter_mappings(mappings, drop_extra_keys=False):
     filtered = {}
     invalid_keysyms = set()
     for keycode, entries in mappings.items():
         mods = modifiers_for(entries)
         if len(mods)>1:
             log.warn("Warning: keymapping removed an invalid keycode entry:")
             log.warn(" keycode %s points to %i modifiers: %s", keycode, len(mods), csv(list(mods)))
             log.warn(" from definition: %s", csv(list(entries)))
             continue
         #now remove entries for keysyms we don't have:
         f_entries = set([(keysym, index) for keysym, index in entries if keysym and X11Keyboard.parse_keysym(keysym) is not None])
         for keysym, _ in entries:
             if keysym and X11Keyboard.parse_keysym(keysym) is None:
                 invalid_keysyms.add(keysym)
         if len(f_entries)==0:
             log("keymapping removed invalid keycode entry %s pointing to only unknown keysyms: %s", keycode, entries)
             continue
         if drop_extra_keys:
             noopt = [keysym for keysym, index in entries if (X11Keyboard.parse_keysym(keysym) is not None and keysym not in OPTIONAL_KEYS)]
             if len(noopt)==0:
                 log("keymapping removed keycode entry %s pointing to optional keys: %s", keycode, entries)
                 continue
         filtered[keycode] = f_entries
     if invalid_keysyms:
         log.warn("the following keysyms are invalid and have not been mapped: %s", ", ".join((str(x) for x in invalid_keysyms)))
     return filtered
Exemple #9
0
 def enable_selections(self, selections):
     #when clients first connect or later through the "clipboard-enable-selections" packet,
     #they can tell us which clipboard selections they want enabled
     #(ie: OSX and win32 only use "CLIPBOARD" by default, and not "PRIMARY" or "SECONDARY")
     log("enabling selections: %s", csv(selections))
     for selection, proxy in self._clipboard_proxies.items():
         proxy.set_enabled(selection in selections)
Exemple #10
0
 def get_layout_spec(self):
     layout = None
     layouts = []
     variant = None
     variants = None
     try:
         l = win32api.GetKeyboardLayoutList()
         log("win32api.GetKeyboardLayoutList()=%s", csv(hex(v) for v in l))
         for hkl in l:
             kbid = hkl & 0xffff
             if kbid in WIN32_LAYOUTS:
                 code, _, _, _, _layout, _variants = WIN32_LAYOUTS.get(kbid)
                 log("found keyboard layout '%s' with variants=%s, code '%s' for kbid=%i (%#x)", _layout, _variants, code, kbid, hkl)
                 if _layout not in layouts:
                     layouts.append(_layout)
     except Exception as e:
         log.error("Error: failed to detect keyboard layouts: %s", e)
     try:
         hkl = win32api.GetKeyboardLayout(0)
         log("win32api.GetKeyboardLayout(0)=%#x", hkl)
         kbid = hkl & 0xffff
         if kbid in WIN32_LAYOUTS:
             code, _, _, _, layout, variants = WIN32_LAYOUTS.get(kbid)
             log("found keyboard layout '%s' with variants=%s, code '%s' for kbid=%i (%#x)", layout, variants, code, kbid, hkl)
         if not layout:
             log("unknown keyboard layout for kbid: %i (%#x)", kbid, hkl)
         else:
             layouts.append(layout)
     except Exception as e:
         log.error("Error: failed to detect keyboard layout: %s", e)
     return layout,layouts,variant,variants
Exemple #11
0
 def get_client_backlog(self):
     packets_backlog, pixels_backlog, bytes_backlog = 0, 0, 0
     if len(self.damage_ack_pending)>0:
         sent_before = time.time()-(self.target_latency+0.020)
         dropped_acks_time = time.time()-60      #1 minute
         drop_missing_acks = []
         for sequence, (start_send_at, start_bytes, end_send_at, end_bytes, pixels) in self.damage_ack_pending.items():
             if end_send_at==0 or start_send_at>sent_before:
                 continue
             if start_send_at<dropped_acks_time:
                 drop_missing_acks.append(sequence)
             else:
                 packets_backlog += 1
                 pixels_backlog += pixels
                 bytes_backlog += (end_bytes - start_bytes)
         log("get_client_backlog missing acks: %s", drop_missing_acks)
         #this should never happen...
         if len(drop_missing_acks)>0:
             log.error("Error: expiring %i missing damage ACK%s,", len(drop_missing_acks), engs(drop_missing_acks))
             log.error(" connection may be closed or closing,")
             log.error(" sequence numbers missing: %s", csv(drop_missing_acks))
             for sequence in drop_missing_acks:
                 try:
                     del self.damage_ack_pending[sequence]
                 except:
                     pass
     return packets_backlog, pixels_backlog, bytes_backlog
 def stop(self):
     log("BonjourPublishers.stop(): %s" % csv(self.publishers))
     for publisher in self.publishers:
         try:
             publisher.stop()
         except Exception as e:
             log.error("Error stopping publisher %s:", publisher)
             log.error(" %s" % publisher, e)
Exemple #13
0
 def init_video_encoders_options(self):
     log("init_video_encoders_options()")
     log(" will try video encoders: %s", csv(self.video_encoders))
     for x in self.video_encoders:
         try:
             mods = get_encoder_module_names(x)
             log(" modules for %s: %s", x, csv(mods))
             for mod in mods:
                 try:
                     self.init_video_encoder_option(mod)
                     break
                 except Exception as e:
                     log(" init_video_encoder_option(%s) error", mod, exc_info=True)
                     log.warn("Warning: cannot load %s video encoder:", mod)
                     log.warn(" %s", e)
         except Exception as e:
             log.warn("Warning: cannot add %s encoder: %s", x, e)
     log("found %i video encoder%s: %s", len(self._video_encoder_specs), engs(self._video_encoder_specs), csv(self._video_encoder_specs))
Exemple #14
0
 def get_keymap_spec(self):
     _print, query, query_struct = self.keyboard.get_keymap_spec()
     if self.layout_option:
         query_struct["layout"] = self.layout_option
     if self.layouts_option:
         query_struct["layouts"] = csv(self.layouts_option)
     if self.variant_option:
         query_struct["variant"] = self.variant_option
     if self.variants_option:
         query_struct["variants"] = csv(self.variants_option)
     if self.options:
         if self.options.lower()=="none":
             query_struct["options"] = ""
         else:
             query_struct["options"] = self.options
     if self.layout_option or self.layouts_option or self.variant_option or self.variants_option or self.options:
         query = xkbmap_query_tostring(query_struct)
     return _print, query, query_struct
Exemple #15
0
 def init_video_decoders_options(self):
     log("init_video_decoders_options()")
     log(" will try video decoders: %s", csv(self.video_decoders))
     for x in self.video_decoders:
         try:
             mod = get_decoder_module_name(x)
             self.init_video_decoder_option(mod)
         except:
             log.warn("Warning: cannot add %s decoder", x, exc_info=True)
     log("found %s video decoder%s: %s", len(self._video_decoder_specs), engs(self._video_decoder_specs), csv(self._video_decoder_specs))
Exemple #16
0
def sound_option_or_all(name, options, all_values):
    if not options:
        v = all_values        #not specified on command line: use default
    else:
        v = []
        invalid_options = []
        for x in options:
            #options is a list, but it may have csv embedded:
            for o in x.split(","):
                o = o.strip()
                if o not in all_values:
                    invalid_options.append(o)
                else:
                    v.append(o)
        if len(invalid_options)>0:
            if all_values:
                log.warn("Warning: invalid value%s for %s: %s", engs(invalid_options), name, csv(invalid_options))
                log.warn(" valid option%s: %s", engs(all_values), csv(all_values))
            else:
                log.warn("Warning: no %ss available", name)
    log("%s=%s", name, csv(v))
    return v
 def filtered_modifiers_set(modifiers):
     m = set()
     for modifier in modifiers:
         if self.xkbmap_mod_managed and modifier in self.xkbmap_mod_managed:
             log("modifier is server managed: %s", modifier)
             continue
         keynames = self.keynames_for_mod.get(modifier)
         if is_ignored(modifier, keynames):
             log("modifier %s ignored (in ignored keynames=%s)", modifier, keynames)
             continue
         m.add(modifier)
     log("filtered_modifiers_set(%s)=%s", modifiers, csv(list(m)))
     return m
Exemple #18
0
def get_codecs():
    global CODECS, gst_major_version
    if CODECS is not None or not has_gst:
        return CODECS or {}
    #populate CODECS:
    CODECS = {}
    for elements in CODEC_OPTIONS:
        encoding = elements[0]
        if encoding in CODECS:
            #we already have one for this encoding
            continue
        if force_enabled(encoding):
            log.info("sound codec %s force enabled", encoding)
        elif len([x for x in elements if (x and (x.find("matroska")>=0 or x.find("gdp")>=0))])>0 and get_gst_version()<(0, 10, 36):
            #outdated versions of gstreamer cause problems with the gdp and matroskademux muxers,
            #the receiver may not be able to process the data
            #and we have no way of knowing what version they have at this point, so just disable those:
            log("avoiding %s with gdp muxer - gstreamer version %s is too old", encoding, get_gst_version())
            continue
        elif encoding==OPUS_GDP and get_gst_version()>=(1, 8):
            log("avoiding %s with gstreamer version %s", encoding, get_gst_version())
            continue
        elif encoding in (OPUS_GDP, OPUS) and OSX:
            log("avoiding %s on Mac OS X", encoding)
            continue
        elif encoding==FLAC:
            #flac problems:
            if WIN32 and gst_major_version==0:
                #the gstreamer 0.10 builds on win32 use the outdated oss build,
                #which includes outdated flac libraries with known CVEs,
                #so avoid using those:
                log("avoiding outdated flac module (likely buggy on win32 with gstreamer 0.10)")
                continue
            elif gst_major_version==1:
                log("skipping flac with GStreamer 1.x to avoid obscure 'not-negotiated' errors I do not have time for")
                continue
        elif encoding==OPUS:
            if gst_major_version<1:
                log("skipping opus with GStreamer 0.10")
                continue
        #verify we have all the elements needed:
        if has_plugins(*elements[1:]):
            #ie: FLAC, "flacenc", "oggmux", "flacdec", "oggdemux" = elements
            encoding, encoder, muxer, decoder, demuxer = elements
            CODECS[encoding] = (encoder, muxer, decoder, demuxer)
    log("initialized sound codecs:")
    for k in [x for x in CODEC_ORDER if x in CODECS]:
        def ci(v):
            return "%-12s" % v
        log("* %-10s : %s", k, csv([ci(v) for v in CODECS[k]]))
    return CODECS
Exemple #19
0
 def init_video_encoder_option(self, encoder_name):
     encoder_module = get_codec(encoder_name)
     log("init_video_encoder_option(%s)", encoder_name)
     log(" module=%s", encoder_module)
     if not encoder_module:
         log(" video encoder '%s' could not be loaded:", encoder_name)
         log(" %s", get_codec_error(encoder_name))
         return
     encoder_type = encoder_module.get_type()
     try:
         encoder_module.init_module()
         self._cleanup_modules.append(encoder_module)
     except Exception as e:
         log(" exception in %s module %s initialization %s: %s", encoder_type, encoder_module.__name__, encoder_module.init_module, e, exc_info=True)
         raise
     encodings = encoder_module.get_encodings()
     log(" %s encodings=%s", encoder_type, csv(encodings))
     for encoding in encodings:
         colorspaces = encoder_module.get_input_colorspaces(encoding)
         log(" %s input colorspaces for %s: %s", encoder_type, encoding, csv(colorspaces))
         for colorspace in colorspaces:
             spec = encoder_module.get_spec(encoding, colorspace)
             self.add_encoder_spec(encoding, colorspace, spec)
def load_video_decoders():
    global VIDEO_DECODERS
    if VIDEO_DECODERS is None:
        VIDEO_DECODERS = {}
        vh = getVideoHelper()
        for encoding in vh.get_decodings():
            specs = vh.get_decoder_specs(encoding)
            for colorspace, decoders in specs.items():
                log("%-5s decoders for %7s: %s", encoding, colorspace, csv([d.get_type() for _, d in decoders]))
                assert len(decoders) > 0
                # use the first one:
                _, decoder_module = decoders[0]
                VIDEO_DECODERS[encoding] = decoder_module
        log("video decoders: %s", dict((e, d.get_type()) for e, d in VIDEO_DECODERS.items()))
    return VIDEO_DECODERS
Exemple #21
0
def import_gst():
    global gst, has_gst, gst_vinfo
    if has_gst is not None:
        return gst

    #hacks to locate gstreamer plugins on win32 and osx:
    if WIN32:
        frozen = hasattr(sys, "frozen") and sys.frozen in ("windows_exe", "console_exe", True)
        log("gstreamer_util: frozen=%s", frozen)
        if frozen:
            #on win32, we keep separate trees
            #because GStreamer 0.10 and 1.x were built using different and / or incompatible version of the same libraries:
            from xpra.platform.paths import get_app_dir
            gst_dir = os.path.join(get_app_dir(), "gstreamer-1.0")     #ie: C:\Program Files\Xpra\gstreamer-0.10
            os.environ["GST_PLUGIN_PATH"] = gst_dir
            gst_bin_dir = os.path.join(gst_dir, "bin")                       #ie: C:\Program Files\Xpra\gstreamer-0.10\bin
            os.environ["PATH"] = os.pathsep.join(x for x in (gst_bin_dir, os.environ.get("PATH", "")) if x)
            sys.path.insert(0, gst_bin_dir)
            scanner = os.path.join(gst_bin_dir, "gst-plugin-scanner.exe")
            if os.path.exists(scanner):
                os.environ["GST_PLUGIN_SCANNER"]    = scanner
            gi_dir = os.path.join(get_app_dir(), "girepository-1.0")
            os.environ["GI_TYPELIB_PATH"]       = gi_dir
    elif OSX:
        bundle_contents = os.environ.get("GST_BUNDLE_CONTENTS")
        log("OSX: GST_BUNDLE_CONTENTS=%s", bundle_contents)
        if bundle_contents:
            os.environ["GST_PLUGIN_PATH"]       = os.path.join(bundle_contents, "Resources", "lib", "gstreamer-1.0")
            os.environ["GST_PLUGIN_SCANNER"]    = os.path.join(bundle_contents, "Resources", "bin", "gst-plugin-scanner-1.0")
            gi_dir = os.path.join(bundle_contents, "Resources", "lib", "girepository-1.0")
            os.environ["GI_TYPELIB_PATH"]       = gi_dir
    log("GStreamer 1.x environment: %s", dict((k,v) for k,v in os.environ.items() if (k.startswith("GST") or k.startswith("GI") or k=="PATH")))
    log("GStreamer 1.x sys.path=%s", csv(sys.path))

    try:
        _gst = import_gst1()
        v = _gst.version()
        if v[-1]==0:
            v = v[:-1]
        gst_vinfo = ".".join((str(x) for x in v))
        gst = _gst
    except Exception as e:
        log("Warning failed to import GStreamer 1.x", exc_info=True)
        log.warn("Warning: failed to import GStreamer 1.x:")
        log.warn(" %s", e)
        return None
    has_gst = gst is not None
    return gst
Exemple #22
0
def get_default_sink():
    DEFAULT_SINK = os.environ.get("XPRA_SOUND_SINK")
    if DEFAULT_SINK:
        SINKS = get_sink_plugins()
        if DEFAULT_SINK not in SINKS:
            log.error("invalid default sound sink: '%s' is not in %s", DEFAULT_SINK, csv(SINKS))
        else:
            return DEFAULT_SINK
    try:
        from xpra.sound.pulseaudio.pulseaudio_util import has_pa
        if has_pa():
            return "pulsesink"
    except ImportError as e:
        log("get_default_sink() no pulsesink: %s", e)
    SINKS = get_sink_plugins()
    return SINKS[0]
Exemple #23
0
 def parse_message0(self, message):
     #message parsing code for GStreamer 0.10
     structure = message.structure
     found = False
     if structure.has_field("bitrate"):
         new_bitrate = int(structure["bitrate"])
         self.update_bitrate(new_bitrate)
         found = True
     if structure.has_field("codec"):
         desc = structure["codec"]
         self.new_codec_description(desc)
         found = True
     if structure.has_field("audio-codec"):
         desc = structure["audio-codec"]
         self.new_codec_description(desc)
         found = True
     if structure.has_field("mode"):
         mode = structure["mode"]
         if self.codec_mode!=mode:
             gstlog("mode: %s", mode)
             self.codec_mode = mode
             self.info["codec_mode"] = self.codec_mode
         found = True
     if structure.has_field("type"):
         if structure["type"]=="volume-changed":
             self.gstloginfo("volumes=%s", csv("%i%%" % (v*100/2**16) for v in structure["volumes"]))
             found = True
             self.info["volume"]  = self.get_volume()
         else:
             self.gstloginfo("type=%s", structure["type"])
     if structure.has_field("container-format"):
         v = structure["container-format"]
         self.new_container_description(v)
         found = True
     if not found:
         #these, we know about, so we just log them:
         for x in ("minimum-bitrate", "maximum-bitrate", "channel-mode"):
             if structure.has_field(x):
                 v = structure[x]
                 gstlog("tag message: %s = %s", x, v)
                 return      #handled
         self.gstloginfo("unknown sound pipeline message %s: %s", message, structure)
         self.gstloginfo(" %s", structure.keys())
Exemple #24
0
def get_default_sink():
    sink = os.environ.get("XPRA_SOUND_SINK")
    sinks = get_sink_plugins()
    if sink:
        if sink not in sinks:
            log.error("invalid default sound sink: '%s' is not in %s", sink, csv(sinks))
        else:
            return sink
    try:
        from xpra.sound.pulseaudio.pulseaudio_util import has_pa, get_pactl_server
        if has_pa():
            s = get_pactl_server()
            if not s:
                log("cannot connect to pulseaudio server?")
            else:
                return "pulsesink"
    except ImportError as e:
        log("get_default_sink() no pulsesink: %s", e)
    return sinks[0]
    def video_init(self):
        enclog("video_init() loading codecs")
        load_codecs(decoders=False)
        enclog("video_init() will try video encoders: %s", csv(self.video_encoder_modules) or "none")
        self.video_helper = getVideoHelper()
        #only use video encoders (no CSC supported in proxy)
        self.video_helper.set_modules(video_encoders=self.video_encoder_modules)
        self.video_helper.init()

        self.video_encoding_defs = {}
        self.video_encoders = {}
        self.video_encoders_dst_formats = []
        self.video_encoders_last_used_time = {}
        self.video_encoder_types = []

        #figure out which encoders we want to proxy for (if any):
        encoder_types = set()
        for encoding in self.video_helper.get_encodings():
            colorspace_specs = self.video_helper.get_encoder_specs(encoding)
            for colorspace, especs in colorspace_specs.items():
                if colorspace not in ("BGRX", "BGRA", "RGBX", "RGBA"):
                    #only deal with encoders that can handle plain RGB directly
                    continue

                for spec in especs:                             #ie: video_spec("x264")
                    spec_props = spec.to_dict()
                    del spec_props["codec_class"]               #not serializable!
                    spec_props["score_boost"] = 50              #we want to win scoring so we get used ahead of other encoders
                    spec_props["max_instances"] = 3             #limit to 3 video streams we proxy for (we really want 2,
                                                                # but because of races with garbage collection, we need to allow more)
                    #store it in encoding defs:
                    self.video_encoding_defs.setdefault(encoding, {}).setdefault(colorspace, []).append(spec_props)
                    encoder_types.add(spec.codec_type)

        enclog("encoder types found: %s", tuple(encoder_types))
        #remove duplicates and use preferred order:
        order = PREFERRED_ENCODER_ORDER[:]
        for x in list(encoder_types):
            if x not in order:
                order.append(x)
        self.video_encoder_types = [x for x in order if x in encoder_types]
        enclog.info("proxy video encoders: %s", ", ".join(self.video_encoder_types))
Exemple #26
0
 def handle(self, packet) -> bool:
     digest = bytestostr(packet[3])
     if not digest.startswith("gss:"):
         #not a gss challenge
         log("%s is not a gss challenge", digest)
         return False
     try:
         import gssapi  #@UnresolvedImport
         self.gssapi = gssapi
         if OSX and False:
             from gssapi.raw import (cython_converters, cython_types,
                                     oids)  # @UnresolvedImport
             assert cython_converters and cython_types and oids
     except ImportError as e:
         log.warn("Warning: cannot use gss authentication handler")
         log.warn(" %s", e)
         return False
     service = bytestostr(digest.split(b":", 1)[1])
     if service not in self.services and "*" not in self.services:
         log.warn("Warning: invalid GSS request for service '%s'", service)
         log.warn(" services supported: %s", csv(self.services))
         return False
     log("gss service=%s", service)
     service_name = self.gssapi.Name(service)
     try:
         ctx = self.gssapi.SecurityContext(name=service_name,
                                           usage="initiate")
         token = ctx.step()
     except Exception as e:
         log("gssapi failure", exc_info=True)
         log.error("Error: gssapi client authentication failure:")
         try:
             for x in str(e).split(":", 2):
                 log.error(" %s", x.lstrip(" "))
         except Exception:
             log.error(" %s", e)
         return False
     log("gss token=%s", repr(token))
     self.client.send_challenge_reply(packet, token)
     return True
Exemple #27
0
 def set_actions(self, actions):
     oldactions = self.actions
     self.actions = actions
     #build the change list for emitting the signal:
     # Four separate types of changes are possible,
     # and the 4 parameters of the change signal reflect these possibilities:
     # - as a list of removed actions
     # - a{sb} a list of actions that had their enabled flag changed
     # - a{sv} a list of actions that had their state changed
     # - a{s(bgav)} a list of new actions added in the same format as the return value of the DescribeAll method"""
     removed = dbus.Array(signature="s")
     enabled_changed = dbus.Array(signature="a{sb}")
     state_changed = dbus.Array(signature="a{sv}")
     added = dbus.Array(signature="a{s(bgav)}")
     all_actions = list(set(oldactions.keys() + actions.keys()))
     self.log(".set_actions(..) all actions=%s", csv(all_actions))
     for action in all_actions:
         if action not in actions:
             removed.append(ds(action))
             self.log(".set_actions(..) removed %s", action)
         elif action not in oldactions:
             action_def = actions[action]
             a = dbus.Struct(self._make_action(*action_def))
             v = dbus.Dictionary({ds(action) : a}, signature="s(bgav)")
             added.append(v)
             self.log(".set_actions(..) added %s=%s", action, action_def)
         else:   #maybe changed state?
             oldaction = oldactions.get(action, [False, None, None]) #default value should be redundant
             newaction = actions.get(action, [False, None, None])    #default value should be redundant
             if oldaction[0]!=newaction[0]:
                 v = dbus.Dictionary({ds(action) : dbus.Boolean(newaction[0])}, signature="sb")
                 enabled_changed.append(v)
                 self.log(".set_actions(..) enabled changed for %s from %s to %s", action, oldaction[0], newaction[0])
             if oldaction[2]!=newaction[2]:
                 v = dbus.Dictionary({ds(action) : newaction[2]}, signature="sv")
                 state_changed.append(v)
                 self.log(".set_actions(..) state changed for %s from %s to %s", action, oldaction[2], newaction[2])
     self.log(".set_actions(..) changes: %s", (removed, enabled_changed, state_changed, added))
     if removed or enabled_changed or state_changed or added:
         self.Changed(removed, enabled_changed, state_changed, added)
Exemple #28
0
 def set_actions(self, actions):
     oldactions = self.actions
     self.actions = actions
     #build the change list for emitting the signal:
     # Four separate types of changes are possible,
     # and the 4 parameters of the change signal reflect these possibilities:
     # - as a list of removed actions
     # - a{sb} a list of actions that had their enabled flag changed
     # - a{sv} a list of actions that had their state changed
     # - a{s(bgav)} a list of new actions added in the same format as the return value of the DescribeAll method"""
     removed = dbus.Array(signature="s")
     enabled_changed = dbus.Array(signature="a{sb}")
     state_changed = dbus.Array(signature="a{sv}")
     added = dbus.Array(signature="a{s(bgav)}")
     all_actions = list(set(oldactions.keys() + actions.keys()))
     self.log(".set_actions(..) all actions=%s", csv(all_actions))
     for action in all_actions:
         if action not in actions:
             removed.append(ds(action))
             self.log(".set_actions(..) removed %s", action)
         elif action not in oldactions:
             action_def = actions[action]
             a = dbus.Struct(self._make_action(*action_def))
             v = dbus.Dictionary({ds(action) : a}, signature="s(bgav)")
             added.append(v)
             self.log(".set_actions(..) added %s=%s", action, action_def)
         else:   #maybe changed state?
             oldaction = oldactions.get(action, [False, None, None]) #default value should be redundant
             newaction = actions.get(action, [False, None, None])    #default value should be redundant
             if oldaction[0]!=newaction[0]:
                 v = dbus.Dictionary({ds(action) : dbus.Boolean(newaction[0])}, signature="sb")
                 enabled_changed.append(v)
                 self.log(".set_actions(..) enabled changed for %s from %s to %s", action, oldaction[0], newaction[0])
             if oldaction[2]!=newaction[2]:
                 v = dbus.Dictionary({ds(action) : newaction[2]}, signature="sv")
                 state_changed.append(v)
                 self.log(".set_actions(..) state changed for %s from %s to %s", action, oldaction[2], newaction[2])
     self.log(".set_actions(..) changes: %s", (removed, enabled_changed, state_changed, added))
     if removed or enabled_changed or state_changed or added:
         self.Changed(removed, enabled_changed, state_changed, added)
Exemple #29
0
    def start_sound_source(self, device=None):
        log("start_sound_source(%s)", device)
        assert self.sound_source is None

        def sound_source_state_changed(*_args):
            self.emit("microphone-changed")

        #find the matching codecs:
        matching_codecs = self.get_matching_codecs(self.microphone_codecs,
                                                   self.server_sound_decoders)
        log("start_sound_source(%s) matching codecs: %s", device,
            csv(matching_codecs))
        if not matching_codecs:
            self.no_matching_codec_error("microphone",
                                         self.server_sound_decoders,
                                         self.microphone_codecs)
            return False
        try:
            from xpra.sound.wrapper import start_sending_sound
            plugins = self.sound_properties.get("plugins")
            ss = start_sending_sound(plugins, self.sound_source_plugin, device
                                     or self.microphone_device, None, 1.0,
                                     False, matching_codecs,
                                     self.server_pulseaudio_server,
                                     self.server_pulseaudio_id)
            if not ss:
                return False
            self.sound_source = ss
            ss.connect("new-buffer", self.new_sound_buffer)
            ss.connect("state-changed", sound_source_state_changed)
            ss.connect("new-stream", self.new_stream)
            ss.start()
            log("start_sound_source(%s) sound source %s started", device, ss)
            return True
        except Exception as e:
            self.may_notify_audio("Failed to start microphone forwarding",
                                  "%s" % e)
            log.error("Error setting up microphone forwarding:")
            log.error(" %s", e)
            return False
Exemple #30
0
 def process_challenge_gss(self, packet):
     digest = packet[3]
     if not digest.startswith(b"gss:"):
         #not a gss challenge
         authlog("%s is not a gss challenge", digest)
         return False
     try:
         import gssapi
         if OSX and False:
             from gssapi.raw import (cython_converters, cython_types, oids)
             assert cython_converters and cython_types and oids
     except ImportError as e:
         authlog("import gssapi", exc_info=True)
         if first_time("no-kerberos"):
             authlog.warn("Warning: gss authentication not supported:")
             authlog.warn(" %s", e)
         return False
     service = bytestostr(digest.split(b":", 1)[1])
     if service not in GSS_SERVICES and "*" not in GSS_SERVICES:
         authlog.warn("Warning: invalid GSS request for service '%s'", service)
         authlog.warn(" services supported: %s", csv(GSS_SERVICES))
         return False
     authlog("gss service=%s", service)
     service_name = gssapi.Name(service)
     try:
         ctx = gssapi.SecurityContext(name=service_name, usage="initiate")
         token = ctx.step()
     except Exception as e:
         authlog("gssapi failure", exc_info=True)
         authlog.error("Error: gssapi client authentication failure:")
         try:
             #split on colon
             for x in str(e).split(":", 2):
                 authlog.error(" %s", x.lstrip(" "))
         except:
             authlog.error(" %s", e)
         return False
     authlog("gss token=%s", repr(token))
     self.send_challenge_reply(packet, token)
     return True
Exemple #31
0
def main():
    from xpra.platform import program_context
    from xpra.log import enable_color
    with program_context("GStreamer-Info", "GStreamer Information"):
        enable_color()
        if "-v" in sys.argv or "--verbose" in sys.argv:
            log.enable_debug()
        import_gst()
        v = get_gst_version()
        if not v:
            print("no gstreamer version information")
        else:
            if v[-1] == 0:
                v = v[:-1]
            gst_vinfo = ".".join((str(x) for x in v))
            print("Loaded Python GStreamer version %s for Python %s.%s" %
                  (gst_vinfo, sys.version_info[0], sys.version_info[1]))
        apn = get_all_plugin_names()
        print("GStreamer plugins found: %s" % csv(apn))
        print("")
        print("GStreamer version: %s" %
              ".".join([str(x) for x in get_gst_version()]))
        print("PyGStreamer version: %s" %
              ".".join([str(x) for x in get_pygst_version()]))
        print("")
        encs = [x for x in CODEC_ORDER if has_encoder(x)]
        decs = [x for x in CODEC_ORDER if has_decoder(x)]
        print("encoders:           %s" % csv(encs))
        print("decoders:           %s" % csv(decs))
        print("muxers:             %s" % csv(get_muxers()))
        print("demuxers:           %s" % csv(get_demuxers()))
        print("stream compressors: %s" % csv(get_stream_compressors()))
        print("source plugins:     %s" %
              csv([x for x in get_source_plugins() if x in apn]))
        print("sink plugins:       %s" %
              csv([x for x in get_sink_plugins() if x in apn]))
        print("default sink:       %s" % get_default_sink_plugin())
Exemple #32
0
def main():
    import sys
    from xpra.os_util import WIN32, OSX, POSIX, bytestostr
    from xpra.util import print_nested_dict, csv
    from xpra.platform import program_context
    from xpra.log import enable_color, enable_debug_for
    with program_context("Keyboard-Tool", "Keyboard Tool"):
        #use the logger for the platform module we import from
        enable_color()
        verbose = "-v" in sys.argv or "--verbose" in sys.argv or \
            (WIN32 and not ("-q" in sys.argv or "--quiet"))
        if verbose:
            enable_debug_for("keyboard")

        #naughty, but how else can I hook this up?
        if POSIX and not OSX:
            try:
                from xpra.x11.bindings.posix_display_source import init_posix_display_source    #@UnresolvedImport
                init_posix_display_source()
            except Exception as e:
                print("failed to connect to the X11 server:")
                print(" %s" % e)
                #hope for the best..

        keyboard = Keyboard()  #pylint: disable=not-callable
        mod_meanings, mod_managed, mod_pointermissing = keyboard.get_keymap_modifiers()
        print("Modifiers:")
        print_nested_dict(mod_meanings)
        print("")
        print("Server Managed                    : %s" % (csv(mod_managed) or "None"))
        print("Missing from pointer events       : %s" % (csv(mod_pointermissing) or "None"))
        print("")
        layout,layouts,variant,variants, options = keyboard.get_layout_spec()
        print("Layout:     '%s'" % bytestostr(layout or b""))
        print("Layouts:    %s" % csv("'%s'" % bytestostr(x) for x in (layouts or [])))
        print("Variant:    '%s'" % bytestostr(variant or b""))
        print("Variants:   %s" % csv("'%s'" % bytestostr(x) for x in (variants or [])))
        print("Options:    %s" % (options))
        print("")
        print("Repeat:     %s" % csv(keyboard.get_keyboard_repeat()))
        if verbose and POSIX:
            keysyms = keyboard.get_x11_keymap()
            if keysyms:
                print("Keysyms:")
                for keycode,keysyms in keysyms.items():
                    print(" %3i    : %s" % (keycode, csv(keysyms)))
    return 0
Exemple #33
0
def get_default_source():
    source = os.environ.get("XPRA_SOUND_SRC")
    sources = get_source_plugins()
    if source:
        if source not in sources:
            log.error("invalid default sound source: '%s' is not in %s", source, csv(sources))
        else:
            return source
    try:
        from xpra.sound.pulseaudio.pulseaudio_util import has_pa, get_pactl_server
        if has_pa():
            s = get_pactl_server()
            if not s:
                log("cannot connect to pulseaudio server?")
            else:
                return "pulsesrc"
    except ImportError as e:
        log("get_default_source() no pulsesrc: %s", e)
    for source in sources:
        if has_plugins(source):
            return source
    return None
Exemple #34
0
 def parse_message0(self, message):
     #message parsing code for GStreamer 0.10
     structure = message.structure
     found = False
     if structure.has_field("bitrate"):
         new_bitrate = int(structure["bitrate"])
         self.update_bitrate(new_bitrate)
         found = True
     if structure.has_field("codec"):
         desc = structure["codec"]
         if self.codec_description!=desc:
             log.info("codec: %s", desc)
             self.codec_description = desc
         found = True
     if structure.has_field("audio-codec"):
         desc = structure["audio-codec"]
         self.new_codec_description(desc)
         found = True
     if structure.has_field("mode"):
         mode = structure["mode"]
         if self.codec_mode!=mode:
             log("mode: %s", mode)
             self.codec_mode = mode
         found = True
     if structure.has_field("type"):
         if structure["type"]=="volume-changed":
             log.info("volumes=%s", csv("%i%%" % (v*100/2**16) for v in structure["volumes"]))
             found = True
         else:
             log.info("type=%s", structure["type"])
     if not found:
         #these, we know about, so we just log them:
         for x in ("minimum-bitrate", "maximum-bitrate", "channel-mode", "container-format"):
             if structure.has_field(x):
                 v = structure[x]
                 log("tag message: %s = %s", x, v)
                 return      #handled
         log.info("unknown sound pipeline message %s: %s", message, structure)
         log.info(" %s", structure.keys())
Exemple #35
0
 def process_packet(self, proto, packet):
     command = bytestostr(packet[0])
     if command == CONNECTION_LOST:
         log("connection-lost: %s, calling stop", packet[1:])
         self.net_stop()
         return
     if command == GIBBERISH:
         log.warn("gibberish received:")
         log.warn(" %s", repr_ellipsized(packet[1], limit=80))
         log.warn(" stopping")
         self.net_stop()
         return
     if command == "stop":
         log("received stop message")
         self.net_stop()
         return
     if command == "exit":
         log("received exit message")
         sys.exit(0)
         return
     #make it easier to hookup signals to methods:
     attr = command.replace("-", "_")
     if self.method_whitelist is not None and attr not in self.method_whitelist:
         log.warn("invalid command %r, not in whitelist: %s", attr,
                  csv(self.method_whitelist))
         return
     wo = self.wrapped_object
     if not wo:
         log("wrapped object is no more, ignoring method call '%s'", attr)
         return
     method = getattr(wo, attr, None)
     if not method:
         log.warn("unknown command: '%s'", attr)
         log.warn(" packet: '%s'", repr_ellipsized(str(packet)))
         return
     if DEBUG_WRAPPER:
         log("calling %s.%s%s", wo, attr, str(tuple(packet[1:]))[:128])
     self.idle_add(method, *packet[1:])
     INJECT_FAULT(proto)
Exemple #36
0
 def get_targets_callback(self, _c, targets, *_args):
     self.log("got targets: %s" % csv(str(x) for x in targets))
     if hasattr(targets, "name"):
         self.log("target is atom: %s" % targets.name())
         targets = []
     filtered = [x for x in (targets or []) if x not in ("MULTIPLE", "TARGETS")]
     ct = self.get_targets.get_active_text()
     if not ct:
         #choose a good default target:
         for x in ("STRING", "UTF8_STRING"):
             if x in filtered:
                 ct = x
                 break
     self.get_targets.get_model().clear()
     self.get_targets.set_sensitive(True)
     i = 0
     for t in filtered:
         self.get_targets.append_text(t)
         if t==ct:
             self.get_targets.set_active(i)
         i += 1
     self.get_targets.show_all()
Exemple #37
0
 def filter_mappings(mappings, drop_extra_keys=False):
     filtered = {}
     invalid_keysyms = set()
     def estr(entries):
         try:
             return csv(list(set(x[0] for x in entries)))
         except:
             return csv(list(entries))
     for keycode, entries in mappings.items():
         mods = modifiers_for(entries)
         if len(mods)>1:
             log.warn("Warning: keymapping changed:")
             log.warn(" keycode %s points to %i modifiers: %s", keycode, len(mods), csv(list(mods)))
             log.warn(" from definition: %s", estr(entries))
             for mod in mods:
                 emod = [entry for entry in entries if modifiers_for([entry])]
                 log.warn(" %s: %s", mod, estr(emod))
             #keep just the first one:
             mods = list(mods)[:1]
             entries = [entry for entry in entries if mods[0] in modifiers_for([entry])]
             log.warn(" keeping: %s for %s", estr(entries), mods[0])
         #now remove entries for keysyms we don't have:
         f_entries = set([(keysym, index) for keysym, index in entries if keysym and X11Keyboard.parse_keysym(keysym) is not None])
         for keysym, _ in entries:
             if keysym and X11Keyboard.parse_keysym(keysym) is None:
                 invalid_keysyms.add(keysym)
         if len(f_entries)==0:
             log("keymapping removed invalid keycode entry %s pointing to only unknown keysyms: %s", keycode, entries)
             continue
         if drop_extra_keys:
             noopt = [keysym for keysym, index in entries if (X11Keyboard.parse_keysym(keysym) is not None and keysym not in OPTIONAL_KEYS)]
             if len(noopt)==0:
                 log("keymapping removed keycode entry %s pointing to optional keys: %s", keycode, entries)
                 continue
         filtered[keycode] = f_entries
     if invalid_keysyms:
         log.warn("Warning: the following keysyms are invalid and have not been mapped")
         log.warn(" %s", csv(invalid_keysyms))
     return filtered
Exemple #38
0
def get_default_sink_plugin():
    sink = os.environ.get("XPRA_SOUND_SINK")
    sinks = get_sink_plugins()
    if sink:
        if sink not in sinks:
            log.error("invalid default sound sink: '%s' is not in %s", sink, csv(sinks))
        else:
            return sink
    try:
        from xpra.sound.pulseaudio.pulseaudio_util import has_pa, get_pactl_server
        if has_pa():
            s = get_pactl_server()
            if not s:
                log("cannot connect to pulseaudio server?")
            else:
                return "pulsesink"
    except ImportError as e:
        log("get_default_sink_plugin() no pulsesink: %s", e)
    for sink in sinks:
        if has_plugins(sink):
            return sink
    return None
Exemple #39
0
 def get_layout_spec(self):
     layout = None
     layouts = []
     variant = None
     variants = None
     options = ""
     try:
         l = _GetKeyboardLayoutList()
         log("GetKeyboardLayoutList()=%s", csv(hex(v) for v in l))
         for hkl in l:
             kbid = hkl & 0xffff
             if kbid in WIN32_LAYOUTS:
                 code, _, _, _, _layout, _variants = WIN32_LAYOUTS.get(kbid)
                 log(
                     "found keyboard layout '%s' with variants=%s, code '%s' for kbid=%i (%#x)",
                     _layout, _variants, code, kbid, hkl)
                 if _layout not in layouts:
                     layouts.append(_layout)
     except Exception as e:
         log.error("Error: failed to detect keyboard layouts:")
         log.error(" %s", e)
     try:
         hkl = GetKeyboardLayout(0)
         log("GetKeyboardLayout(0)=%#x", hkl)
         kbid = hkl & 0xffff
         if kbid in WIN32_LAYOUTS:
             code, _, _, _, layout, variants = WIN32_LAYOUTS.get(kbid)
             log(
                 "found keyboard layout '%s' with variants=%s, code '%s' for kbid=%i (%#x)",
                 layout, variants, code, kbid, hkl)
         if not layout:
             log("unknown keyboard layout for kbid: %i (%#x)", kbid, hkl)
         else:
             layouts.append(layout)
     except Exception as e:
         log.error("Error: failed to detect keyboard layout:")
         log.error(" %s", e)
     return layout, layouts, variant, variants, options
Exemple #40
0
def handle_socket_error(sockpath, sperms, e):
    log = get_network_logger()
    log("socket creation error", exc_info=True)
    if sockpath.startswith("/var/run/xpra") or sockpath.startswith(
            "/run/xpra"):
        log.info("cannot create group socket '%s'", sockpath)
        log.info(" %s", e)
        dirname = sockpath[:sockpath.find("xpra") + len("xpra")]
        if not os.path.exists(dirname):
            log.info(" %s does not exist", dirname)
        #only show extra information if the socket permissions
        #would have been accessible by the group:
        elif POSIX and (sperms & 0o40):
            uid = getuid()
            username = get_username_for_uid(uid)
            groups = get_groups(username)
            log.info(" user '%s' is a member of groups: %s", username,
                     csv(groups) or "no groups!")
            if "xpra" not in groups:
                log.info(
                    "  add 'xpra' group membership to enable group socket sharing"
                )
            for x in path_permission_info(dirname):
                log.info("  %s", x)
    elif sockpath.startswith("/var/run/user") or sockpath.startswith(
            "/run/user"):
        log.warn("Warning: cannot create socket '%s':", sockpath)
        log.warn(" %s", e)
        run_user = sockpath.split("/user")[0] + "/user"
        if not os.path.exists(run_user):
            log.warn(" %s does not exist", run_user)
        else:
            log.warn(" ($XDG_RUNTIME_DIR has not been created?)")
    else:
        log.error("Error: failed to create socket '%s':", sockpath)
        log.error(" %s", e)
        raise InitExit(EXIT_SOCKET_CREATION_ERROR,
                       "failed to create socket %s" % sockpath)
Exemple #41
0
def do_import_gst():
    global gst
    if gst is not None:
        return gst

    #hacks to locate gstreamer plugins on win32 and osx:
    if WIN32:
        frozen = getattr(sys, "frozen", None) in ("windows_exe", "console_exe", True)
        log("gstreamer_util: frozen=%s", frozen)
        if frozen:
            from xpra.platform.paths import get_app_dir
            gst_dir = os.path.join(get_app_dir(), "lib", "gstreamer-1.0")   #ie: C:\Program Files\Xpra\lib\gstreamer-1.0
            os.environ["GST_PLUGIN_PATH"] = gst_dir
    elif OSX:
        bundle_contents = os.environ.get("GST_BUNDLE_CONTENTS")
        log("OSX: GST_BUNDLE_CONTENTS=%s", bundle_contents)
        if bundle_contents:
            rsc_dir = os.path.join(bundle_contents, "Resources")
            os.environ["GST_PLUGIN_PATH"]       = os.path.join(rsc_dir, "lib", "gstreamer-1.0")
            os.environ["GST_PLUGIN_SCANNER"]    = os.path.join(rsc_dir, "bin", "gst-plugin-scanner-1.0")
    log("GStreamer 1.x environment: %s",
        dict((k,v) for k,v in os.environ.items() if (k.startswith("GST") or k.startswith("GI") or k=="PATH")))
    log("GStreamer 1.x sys.path=%s", csv(sys.path))

    try:
        log("import gi")
        import gi
        gi.require_version('Gst', '1.0')
        from gi.repository import Gst           #@UnresolvedImport
        log("Gst=%s", Gst)
        Gst.init(None)
        gst = Gst
    except Exception as e:
        log("Warning failed to import GStreamer 1.x", exc_info=True)
        log.warn("Warning: failed to import GStreamer 1.x:")
        log.warn(" %s", e)
        return None
    return gst
Exemple #42
0
 def init_csc_option(self, csc_name):
     csc_module = get_codec(csc_name)
     log("init_csc_option(%s)", csc_name)
     log(" module=%s", csc_module)
     if csc_module is None:
         log(" csc module %s could not be loaded:", csc_name)
         log(" %s", get_codec_error(csc_name))
         return
     csc_type = csc_module.get_type()
     try:
         csc_module.init_module()
         self._cleanup_modules.append(csc_module)
     except Exception as e:
         log("exception in %s module initialization %s: %s", csc_type, csc_module.init_module, e, exc_info=True)
         log.warn("Warning: cannot use %s module %s: %s", csc_type, csc_module, e)
         return
     in_cscs = csc_module.get_input_colorspaces()
     for in_csc in in_cscs:
         out_cscs = csc_module.get_output_colorspaces(in_csc)
         log("%s output colorspaces for %s: %s", csc_module.get_type(), in_csc, csv(out_cscs))
         for out_csc in out_cscs:
             spec = csc_module.get_spec(in_csc, out_csc)
             self.add_csc_spec(in_csc, out_csc, spec)
Exemple #43
0
 def parse_server_capabilities(self, c : typedict) -> bool:
     if self.remote_logging.lower() in ("send", "both", "yes", "true", "on") and (
         #'remote-logging.receive' was only added in v4.1 so check both:
         c.boolget("remote-logging") or c.boolget("remote-logging.receive")):
         #check for debug:
         from xpra.log import is_debug_enabled
         conflict = tuple(v for v in ("network", "crypto", "udp", "websocket") if is_debug_enabled(v))
         if conflict:
             log.warn("Warning: cannot enable remote logging")
             log.warn(" because debug logging is enabled for: %s", csv(conflict))
             return True
         log.info("enabled remote logging")
         if not self.log_both:
             log.info(" see server log file for further output")
         self.local_logging = set_global_logging_handler(self.remote_logging_handler)
     elif self.remote_logging.lower()=="receive":
         self.request_server_log = c.boolget("remote-logging.send")
         if not self.request_server_log:
             log.warn("Warning: cannot receive log output from the server")
             log.warn(" the feature is not enabled or not supported by the server")
         else:
             self.after_handshake(self.start_receiving_logging)
     return True
 def control_command_key(self, keycode_str, press=True):
     if self.readonly:
         return
     try:
         if keycode_str.startswith("0x"):
             keycode = int(keycode_str, 16)
         else:
             keycode = int(keycode_str)
         assert keycode > 0 and keycode <= 255
     except:
         raise ControlError(
             "invalid keycode specified: '%s' (must be a number between 1 and 255)"
             % keycode_str) from None
     if press is not True:
         if press in ("1", "press"):
             press = True
         elif press in ("0", "unpress"):
             press = False
         else:
             raise ControlError(
                 "if present, the press argument must be one of: %s" % csv(
                     ("1", "press", "0", "unpress")))
     self.fake_key(keycode, press)
Exemple #45
0
 def init_csc_option(self, csc_name):
     csc_module = get_codec(csc_name)
     log("init_csc_option(%s)", csc_name)
     log(" module=%s", csc_module)
     if csc_module is None:
         log(" csc module %s could not be loaded:", csc_name)
         log(" %s", get_codec_error(csc_name))
         return
     csc_type = csc_module.get_type()
     try:
         csc_module.init_module()
         self._cleanup_modules.append(csc_module)
     except Exception as e:
         log("exception in %s module initialization %s: %s", csc_type, csc_module.init_module, e, exc_info=True)
         log.warn("Warning: cannot use %s module %s: %s", csc_type, csc_module, e)
         return
     in_cscs = csc_module.get_input_colorspaces()
     for in_csc in in_cscs:
         out_cscs = csc_module.get_output_colorspaces(in_csc)
         log("%s output colorspaces for %s: %s", csc_module.get_type(), in_csc, csv(out_cscs))
         for out_csc in out_cscs:
             spec = csc_module.get_spec(in_csc, out_csc)
             self.add_csc_spec(in_csc, out_csc, spec)
Exemple #46
0
def main():
    from xpra.codecs.loader import log as loader_log, load_codecs
    from xpra.log import enable_color
    from xpra.platform import init, clean
    try:
        init("Video Helper")
        enable_color()
        if "-v" in sys.argv or "--verbose" in sys.argv:
            loader_log.enable_debug()
            log.enable_debug()
        load_codecs()
        vh = getVideoHelper()
        vh.set_modules(ALL_VIDEO_ENCODER_OPTIONS, ALL_CSC_MODULE_OPTIONS, ALL_VIDEO_DECODER_OPTIONS)
        vh.init()
        log.info("VideoHelper.get_info():")
        info = vh.get_info()
        for k in sorted(info.keys()):
            v = info.get(k)
            if type(v) in (list, tuple):
                v = csv(v)
            log.info("%s=%s", k, v)
    finally:
        clean()
Exemple #47
0
def get_sockopt_tcp_info(sock, TCP_INFO, attributes=POSIX_TCP_INFO):
    def get_tcpinfo_class(fields):
        class TCPInfo(Structure):
            _fields_ = tuple(fields)
            def __repr__(self):
                return "TCPInfo(%s)" % self.getdict()
            def getdict(self):
                return {k[0] : getattr(self, k[0]) for k in self._fields_}
        return TCPInfo
    #calculate full structure size with all the fields defined:
    tcpinfo_class = get_tcpinfo_class(attributes)
    tcpinfo_size = sizeof(tcpinfo_class)
    data = sock.getsockopt(socket.SOL_TCP, TCP_INFO, tcpinfo_size)
    data_size = len(data)
    #but only define fields in the ctypes.Structure
    #if they are actually present in the returned data:
    while tcpinfo_size>data_size:
        #trim it down:
        attributes = attributes[:-1]
        tcpinfo_class = get_tcpinfo_class(attributes)
        tcpinfo_size = sizeof(tcpinfo_class)
    log = get_network_logger()
    if tcpinfo_size==0:
        log("getsockopt(SOL_TCP, TCP_INFO, %i) no data", tcpinfo_size)
        return {}
    #log("total size=%i for fields: %s", size, csv(fdef[0] for fdef in fields))
    try:
        tcpinfo = tcpinfo_class.from_buffer_copy(data[:tcpinfo_size])
    except ValueError as e:
        log("getsockopt(SOL_TCP, TCP_INFO, %i)", tcpinfo_size, exc_info=True)
        log("TCPInfo fields=%s", csv(tcpinfo_class._fields_))
        log.warn("Warning: failed to get TCP_INFO for %s", sock)
        log.warn(" %s", e)
        return {}
    d = tcpinfo.getdict()
    log("getsockopt(SOL_TCP, TCP_INFO, %i)=%s", tcpinfo_size, d)
    return d
Exemple #48
0
def main():
    from xpra.codecs.loader import log as loader_log, load_codecs
    from xpra.log import enable_color
    from xpra.platform import init, clean
    try:
        init("Video Helper")
        enable_color()
        if "-v" in sys.argv or "--verbose" in sys.argv:
            loader_log.enable_debug()
            log.enable_debug()
        load_codecs()
        vh = getVideoHelper()
        vh.set_modules(ALL_VIDEO_ENCODER_OPTIONS, ALL_CSC_MODULE_OPTIONS,
                       ALL_VIDEO_DECODER_OPTIONS)
        vh.init()
        log.info("VideoHelper.get_info():")
        info = vh.get_info()
        for k in sorted(info.keys()):
            v = info.get(k)
            if type(v) in (list, tuple):
                v = csv(v)
            log.info("%s=%s", k, v)
    finally:
        clean()
Exemple #49
0
 def start_receiving_sound(self):
     """ ask the server to start sending sound and emit the client signal """
     log("start_receiving_sound() sound sink=%s", self.sound_sink)
     enabled = False
     try:
         if self.sound_sink is not None:
             log("start_receiving_sound: we already have a sound sink")
             enabled = True
             return
         if not self.server_sound_send:
             log.error("Error receiving sound: support not enabled on the server")
             return
         if not self.audio_loop_check("speaker"):
             return
         #choose a codec:
         matching_codecs = self.get_matching_codecs(self.speaker_codecs, self.server_sound_encoders)
         log("start_receiving_sound() matching codecs: %s", csv(matching_codecs))
         if not matching_codecs:
             self.no_matching_codec_error("speaker", self.server_sound_encoders, self.speaker_codecs)
             return
         codec = matching_codecs[0]
         if not self.server_ogg_latency_fix and codec in ("flac", "opus", "speex"):
             log.warn("Warning: this server's sound support is out of date")
             log.warn(" the sound latency with the %s codec will be high", codec)
         def sink_ready(*args):
             scodec = codec
             log("sink_ready(%s) codec=%s (server codec name=%s)", args, codec, scodec)
             self.send("sound-control", "start", scodec)
             return False
         self.on_sink_ready = sink_ready
         enabled = self.start_sound_sink(codec)
     finally:
         if self.speaker_enabled!=enabled:
             self.speaker_enabled = enabled
             self.emit("speaker-changed")
         log("start_receiving_sound() done, speaker_enabled=%s", enabled)
Exemple #50
0
 def _print_file(self, filename, mimetype, printer, title, options):
     import time
     from xpra.platform.printing import print_files, printing_finished, get_printers
     printers = get_printers()
     if printer not in printers:
         printlog.error("Error: printer '%s' does not exist!", printer)
         printlog.error(" printers available: %s", csv(printers.keys()) or "none")
         return
     def delfile():
         if not DELETE_PRINTER_FILE:
             return
         try:
             os.unlink(filename)
         except:
             printlog("failed to delete print job file '%s'", filename)
         return False
     job = print_files(printer, [filename], title, options)
     printlog("printing %s, job=%s", filename, job)
     if job<=0:
         printlog("printing failed and returned %i", job)
         delfile()
         return
     start = time.time()
     def check_printing_finished():
         done = printing_finished(job)
         printlog("printing_finished(%s)=%s", job, done)
         if done:
             delfile()
             return False
         if time.time()-start>10*60:
             printlog.warn("print job %s timed out", job)
             delfile()
             return False
         return True #try again..
     if check_printing_finished():
         self.timeout_add(10000, check_printing_finished)
Exemple #51
0
 def set_modules(self, video_encoders=(), csc_modules=(), video_decoders=()):
     log("set_modules%s", (video_encoders, csc_modules, video_decoders))
     assert not self._initialized, "too late to set modules, the helper is already initialized!"
     def filt(name, inlist, all_list):
         exclist = list(x[1:] for x in inlist if x and x.startswith("-"))
         inclist = list(x for x in inlist if x and not x.startswith("-"))
         if "all" in inclist:
             inclist = all_list
         else:
             notfound = tuple(x for x in (exclist+inclist) if x and x not in all_list)
             if notfound:
                 log.warn("Warning: ignoring unknown %s: %s", name, csv(notfound))
         return tuple(x for x in inclist if x not in exclist)
     self.video_encoders = filt("video encoders" , video_encoders,   ALL_VIDEO_ENCODER_OPTIONS)
     self.csc_modules    = filt("csc modules"    , csc_modules,      ALL_CSC_MODULE_OPTIONS)
     self.video_decoders = filt("video decoders" , video_decoders,   ALL_VIDEO_DECODER_OPTIONS)
     log("VideoHelper.set_modules(%r, %r, %r) video encoders=%s, csc=%s, video decoders=%s",
         csv(video_encoders), csv(csc_modules), csv(video_decoders),
         csv(self.video_encoders), csv(self.csc_modules), csv(self.video_decoders))
Exemple #52
0
 def copy_to_clipboard(self, *_args):
     w = self._window
     if not w:
         return
     info = {
         "wid": w._id,
         "title": w.get_title(),
         "override-redirect": w._override_redirect,
         "state": get_window_state(w),
         "attributes": get_window_attributes(w),
         "focused": w._focused,
         "buttons": csv(b for b, s in w.button_state.items() if s)
         or "none",
         "gravity": GRAVITY_STR.get(w.window_gravity, "invalid"),
         "content-type": w.content_type or "unknown",
         "pixel-depth": w.pixel_depth or 24,
         "alpha": w._window_alpha,
         "opengl": w.is_GL(),
         "geometry": geom_str(list(w._pos) + list(w._size)),
         "outer-geometry":
         geom_str(list(w.get_position()) + list(w.get_size())),
         "inner-geometry": geom_str(w.get_drawing_area_geometry()),
         "offsets": csv(str(x) for x in (w.window_offset or ())) or "none",
         "frame-extents": csv(w._current_frame_extents or []) or "none",
         "max-size": csv(w.max_window_size),
         "size-constraints": hsc(w.size_constraints),
     }
     #backing:
     b = w._backing
     if b:
         info.update({
             "size": csv(b.size),
             "render-size": csv(b.render_size),
             "backing-offsets": csv(b.offsets),
         })
     text = "\n".join("%s=%s" % (k, v) for k, v in info.items())
     clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
     clipboard.set_text(text, len(text))
Exemple #53
0
    def set_modules(self, video_encoders=(), csc_modules=(),
                    video_decoders=()):
        assert not self._initialized, "too late to set modules, the helper is already initialized!"

        def filt(name, inlist, all_list):
            notfound = tuple(x for x in inlist if x and x not in all_list)
            if notfound:
                log.warn("Warning: ignoring unknown %s: %s", name,
                         csv(notfound))
            return tuple(x for x in inlist if x in all_list)

        self.video_encoders = filt("video encoders", video_encoders,
                                   ALL_VIDEO_ENCODER_OPTIONS)
        self.csc_modules = filt("csc modules", csc_modules,
                                ALL_CSC_MODULE_OPTIONS)
        self.video_decoders = filt("video decoders", video_decoders,
                                   ALL_VIDEO_DECODER_OPTIONS)
        log(
            "VideoHelper.set_modules(%s, %s, %s) video encoders=%s, csc=%s, video decoders=%s",
            csv(video_encoders), csv(csc_modules), csv(video_decoders),
            csv(self.video_encoders), csv(self.csc_modules),
            csv(self.video_decoders))
Exemple #54
0
 def filt(name, inlist, all_list):
     notfound = [x for x in inlist if x and x not in all_list]
     if notfound:
         log.warn("ignoring unknown %s: %s", name, csv(notfound))
     return [x for x in inlist if x in all_list]
Exemple #55
0
    def init(self, opts):
        self.av_sync = opts.av_sync
        self.sound_properties = typedict()
        self.speaker_allowed = sound_option(opts.speaker) in ("on", "off")
        #ie: "on", "off", "on:Some Device", "off:Some Device"
        mic = [x.strip() for x in opts.microphone.split(":", 1)]
        self.microphone_allowed = sound_option(mic[0]) in ("on", "off")
        self.microphone_device = None
        if self.microphone_allowed and len(mic) == 2:
            self.microphone_device = mic[1]
        self.sound_source_plugin = opts.sound_source

        def sound_option_or_all(*_args):
            return []

        if self.speaker_allowed or self.microphone_allowed:
            try:
                from xpra.sound import common
                assert common
            except ImportError as e:
                self.may_notify_audio(
                    "No Audio", "audio subsystem is not installed\n" +
                    " speaker and microphone forwarding are disabled")
                self.speaker_allowed = False
                self.microphone_allowed = False
            else:
                try:
                    from xpra.sound.common import sound_option_or_all
                    from xpra.sound.wrapper import query_sound
                    self.sound_properties = query_sound()
                    assert self.sound_properties, "query did not return any data"

                    def vinfo(k):
                        val = self.sound_properties.strtupleget(k)
                        assert val, "%s not found in sound properties" % k
                        return ".".join(val[:3])

                    bits = self.sound_properties.intget("python.bits", 32)
                    log.info("GStreamer version %s for Python %s %s-bit",
                             vinfo("gst.version"), vinfo("python.version"),
                             bits)
                except Exception as e:
                    log("failed to query sound", exc_info=True)
                    log.error("Error: failed to query sound subsystem:")
                    log.error(" %s", e)
                    self.speaker_allowed = False
                    self.microphone_allowed = False
        encoders = self.sound_properties.strtupleget("encoders")
        decoders = self.sound_properties.strtupleget("decoders")
        self.speaker_codecs = sound_option_or_all("speaker-codec",
                                                  opts.speaker_codec, decoders)
        self.microphone_codecs = sound_option_or_all("microphone-codec",
                                                     opts.microphone_codec,
                                                     encoders)
        if not self.speaker_codecs:
            self.speaker_allowed = False
        if not self.microphone_codecs:
            self.microphone_allowed = False
        self.speaker_enabled = self.speaker_allowed and sound_option(
            opts.speaker) == "on"
        self.microphone_enabled = self.microphone_allowed and opts.microphone.lower(
        ) == "on"
        log("speaker: codecs=%s, allowed=%s, enabled=%s", encoders,
            self.speaker_allowed, csv(self.speaker_codecs))
        log("microphone: codecs=%s, allowed=%s, enabled=%s, default device=%s",
            decoders, self.microphone_allowed, csv(self.microphone_codecs),
            self.microphone_device)
        log("av-sync=%s", self.av_sync)
        if POSIX and not OSX:
            try:
                from xpra.sound.pulseaudio.pulseaudio_util import get_info as get_pa_info
                pa_info = get_pa_info()
                log("pulseaudio info=%s", pa_info)
                self.sound_properties.update(pa_info)
            except ImportError as e:
                log.warn("Warning: no pulseaudio information available")
                log.warn(" %s", e)
            except Exception:
                log.error("failed to add pulseaudio info", exc_info=True)
        #audio tagging:
        self.init_audio_tagging(opts.tray_icon)
Exemple #56
0
 def __init__(self,
              sink_type=None,
              sink_options={},
              codecs=get_decoders(),
              codec_options={},
              volume=1.0):
     if not sink_type:
         sink_type = get_default_sink()
     if sink_type not in get_sink_plugins():
         raise InitExit(1, "invalid sink: %s" % sink_type)
     matching = [
         x for x in CODEC_ORDER if (x in codecs and x in get_decoders())
     ]
     log("SoundSink(..) found matching codecs %s", matching)
     if not matching:
         raise InitExit(
             1,
             "no matching codecs between arguments '%s' and supported list '%s'"
             % (csv(codecs), csv(get_decoders().keys())))
     codec = matching[0]
     decoder, parser, stream_compressor = get_decoder_elements(codec)
     SoundPipeline.__init__(self, codec)
     self.container_format = (parser
                              or "").replace("demux",
                                             "").replace("depay", "")
     self.sink_type = sink_type
     self.stream_compressor = stream_compressor
     log("container format=%s, stream_compressor=%s, sink type=%s",
         self.container_format, self.stream_compressor, self.sink_type)
     self.levels = deque(maxlen=100)
     self.volume = None
     self.src = None
     self.queue = None
     self.normal_volume = volume
     self.target_volume = volume
     self.volume_timer = 0
     self.overruns = 0
     self.underruns = 0
     self.overrun_events = deque(maxlen=100)
     self.queue_state = "starting"
     self.last_data = None
     self.last_underrun = 0
     self.last_overrun = 0
     self.refill = True
     self.last_max_update = monotonic_time()
     self.last_min_update = monotonic_time()
     self.level_lock = Lock()
     pipeline_els = []
     appsrc_el = [
         "appsrc",
         #"do-timestamp=1",
         "name=src",
         "emit-signals=0",
         "block=0",
         "is-live=0",
         "stream-type=%s" % STREAM_TYPE,
         "format=%s" % BUFFER_FORMAT
     ]
     pipeline_els.append(" ".join(appsrc_el))
     if parser:
         pipeline_els.append(parser)
     if decoder:
         decoder_str = plugin_str(decoder, codec_options)
         pipeline_els.append(decoder_str)
     pipeline_els.append("audioconvert")
     pipeline_els.append("audioresample")
     if QUEUE_TIME > 0:
         pipeline_els.append(" ".join([
             "queue", "name=queue", "min-threshold-time=0",
             "max-size-buffers=0", "max-size-bytes=0",
             "max-size-time=%s" % QUEUE_TIME,
             "leaky=%s" % QUEUE_LEAK
         ]))
     pipeline_els.append("volume name=volume volume=0")
     sink_attributes = SINK_SHARED_DEFAULT_ATTRIBUTES.copy()
     #anything older than this may cause problems (ie: centos 6.x)
     #because the attributes may not exist
     sink_attributes.update(SINK_DEFAULT_ATTRIBUTES.get(sink_type, {}))
     get_options_cb = DEFAULT_SINK_PLUGIN_OPTIONS.get(
         sink_type.replace("sink", ""))
     if get_options_cb:
         v = get_options_cb()
         log("%s()=%s", get_options_cb, v)
         sink_attributes.update(v)
     sink_attributes.update(sink_options)
     sink_str = plugin_str(sink_type, sink_attributes)
     pipeline_els.append(sink_str)
     if not self.setup_pipeline_and_bus(pipeline_els):
         return
     self.volume = self.pipeline.get_by_name("volume")
     self.src = self.pipeline.get_by_name("src")
     self.queue = self.pipeline.get_by_name("queue")
     if self.queue:
         if QUEUE_SILENT:
             self.queue.set_property("silent", False)
         else:
             self.queue.connect("overrun", self.queue_overrun)
             self.queue.connect("underrun", self.queue_underrun)
             self.queue.connect("running", self.queue_running)
             self.queue.connect("pushing", self.queue_pushing)
Exemple #57
0
    "NETWORK": 64,
    "EXPAND": 16384,
    "CONTAINER": 32768,
    "ICON1": 65536 * 1,
    "ICON2": 65536 * 2,
    "ICON3": 65536 * 3,
    "ICON4": 65536 * 4,
    "ICON5": 65536 * 5,
    "ICON6": 65536 * 6,
    "ICON7": 65536 * 7,
    "ICON8": 65536 * 8,
}
PRINTER_ENUM_NAMES = dict((v, k) for k, v in PRINTER_ENUM_VALUES.items())
log("PRINTER_ENUM_VALUES: %s", PRINTER_ENUM_VALUES)

log("PRINTER_FLAGS=%s", csv(PRINTER_FLAGS))
VALID_PRINTER_FLAGS = ("LOCAL", "SHARED", "CONNECTIONS", "NETWORK", "REMOTE")
PRINTER_ENUMS = []
for v in PRINTER_FLAGS:  #ie: "SHARED+NETWORK+CONNECTIONS"
    flags = v.replace('|', '+').split(
        "+")  #ie: ["SHARED", "NETWORK", "CONNECTIONS"]
    values = []
    for flag in flags:  #ie: "SHARED"
        if flag not in VALID_PRINTER_FLAGS:
            log.warn(
                "Warning: the following printer flag is invalid and will be ignored: %s",
                flag)
        else:
            values.append(flag)  #ie: "SHARED"
    PRINTER_ENUMS.append(values)
log("PRINTER_ENUMS=%s", PRINTER_ENUMS)
Exemple #58
0
    def _print_file(self, filename, mimetype, options):
        printlog("print_file%s", (filename, mimetype, options))
        printer = options.strget("printer")
        title = options.strget("title")
        copies = options.intget("copies", 1)
        if title:
            printlog.info(" sending '%s' to printer '%s'", title, printer)
        else:
            printlog.info(" sending to printer '%s'", printer)
        from xpra.platform.printing import print_files, printing_finished, get_printers
        printers = get_printers()

        def delfile():
            if not DELETE_PRINTER_FILE:
                return
            try:
                os.unlink(filename)
            except:
                printlog("failed to delete print job file '%s'", filename)
            return False

        if not printer:
            printlog.error("Error: the printer name is missing")
            printlog.error(" printers available: %s",
                           csv(printers.keys()) or "none")
            delfile()
            return
        if printer not in printers:
            printlog.error("Error: printer '%s' does not exist!", printer)
            printlog.error(" printers available: %s",
                           csv(printers.keys()) or "none")
            delfile()
            return
        try:
            job_options = options.get("options")
            job_options["copies"] = copies
            job = print_files(printer, [filename], title, job_options)
        except Exception as e:
            printlog("print_files%s", (printer, [filename], title, options),
                     exc_info=True)
            printlog.error("Error: cannot print file '%s'",
                           os.path.basename(filename))
            printlog.error(" %s", e)
            delfile()
            return
        printlog("printing %s, job=%s", filename, job)
        if job <= 0:
            printlog("printing failed and returned %i", job)
            delfile()
            return
        start = monotonic_time()

        def check_printing_finished():
            done = printing_finished(job)
            printlog("printing_finished(%s)=%s", job, done)
            if done:
                delfile()
                return False
            if monotonic_time() - start >= PRINT_JOB_TIMEOUT:
                printlog.warn("Warning: print job %s timed out", job)
                delfile()
                return False
            return True  #try again..

        if check_printing_finished():
            #check every 10 seconds:
            self.timeout_add(10000, check_printing_finished)
Exemple #59
0
def keymap_to_xmodmap(trans_keycodes):
    """
        Given a dict with keycodes as keys and lists of keyboard entries as values,
        (keysym, keycode, index)
        produce a list of xmodmap instructions to set the x11 keyboard to match it,
        in the form:
        ("keycode", keycode, [keysyms])
    """
    missing_keysyms = []  #the keysyms lookups which failed
    instructions = []
    all_entries = []
    for entries in trans_keycodes.values():
        all_entries += entries
    keysyms_per_keycode = max([index for _, index in all_entries]) + 1
    for server_keycode, entries in trans_keycodes.items():
        keysyms = [None] * keysyms_per_keycode
        names = [""] * keysyms_per_keycode
        sentries = sorted(entries, key=lambda x: x[1])
        for name, index in sentries:
            assert 0 <= index and index < keysyms_per_keycode
            try:
                keysym = X11Keyboard.parse_keysym(name)
            except:
                keysym = None
            if keysym is None:
                if name != "":
                    missing_keysyms.append(name)
            else:
                if keysyms[index] is not None:
                    #if the client provides multiple keysyms for the same index,
                    #replace with the new one if the old one exists elsewhere,
                    #or skip it if we have another entry for it
                    can_override = any(True for i, v in enumerate(keysyms)
                                       if i < index and v == keysyms[index])
                    can_skip = any(True for i, v in enumerate(keysyms)
                                   if i != index and v == keysym)
                    if can_override or can_skip:
                        l = log.debug
                    else:
                        l = log.warn
                    l(
                        "Warning: more than one keysym for keycode %-3i at index %i:",
                        server_keycode, index)
                    l(" entries=%s", csv(tuple(sentries)))
                    l(" keysyms=%s", csv(keysyms))
                    l(" assigned keysym=%s", names[index])
                    l(" wanted keysym=%s", name)
                    if can_override:
                        l(" current value also found at another index, overriding it"
                          )
                    elif can_skip:
                        l(" new value also found elsewhere, skipping it")
                    else:
                        continue
                names[index] = name
                keysyms[index] = keysym
                if name in DEBUG_KEYSYMS:
                    log.info("keymap_to_xmodmap: keysyms[%s]=%s (%s)", index,
                             keysym, name)
        #remove empty keysyms:
        while len(keysyms) > 0 and keysyms[0] is None:
            keysyms = keysyms[1:]
        l = log
        if [k for k in keysyms if k in DEBUG_KEYSYMS]:
            l = log.info
        l("%s: %s -> %s", server_keycode, names, keysyms)
        instructions.append(("keycode", server_keycode, keysyms))

    if len(missing_keysyms) > 0:
        log.error("cannot find the X11 keysym for the following key names: %s",
                  set(missing_keysyms))
    log("instructions=%s", instructions)
    return instructions
Exemple #60
0
 def estr(entries):
     try:
         return csv(tuple(set(x[0] for x in entries)))
     except:
         return csv(tuple(entries))