Example #1
0
 def filter_mappings(mappings):
     filtered = {}
     for keycode, entries in mappings.items():
         mods = modifiers_for(entries)
         if len(mods)>1:
             log.warn("keymapping removed invalid keycode entry %s pointing to more than one modifier (%s): %s", keycode, mods, entries)
             continue
         #now remove entries for keysyms we don't have:
         f_entries = set([(keysym, index) for keysym, index in entries if parse_keysym(keysym) is not None])
         if len(f_entries)==0:
             log("keymapping removed invalid keycode entry %s pointing to only unknown keysyms: %s", keycode, entries)
             continue
         filtered[keycode] = f_entries
     return filtered
Example #2
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
        for name, index in entries:
            assert 0 <= index and index < keysyms_per_keycode
            names[index] = name
            try:
                keysym = parse_keysym(name)
            except:
                keysym = None
            if keysym is None:
                if name != "":
                    missing_keysyms.append(name)
            else:
                if keysyms[index] is not None:
                    log.warn(
                        "we already have a keysym for %s at index %s: %s, entries=%s",
                        server_keycode, index, keysyms[index], entries)
                else:
                    keysyms[index] = keysym
        #remove empty keysyms:
        while len(keysyms) > 0 and keysyms[0] is None:
            keysyms = keysyms[1:]
        debug("%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))
    debug("instructions=%s", instructions)
    return instructions
Example #3
0
 def filter_mappings(mappings):
     filtered = {}
     for keycode, entries in mappings.items():
         mods = modifiers_for(entries)
         if len(mods) > 1:
             log.warn(
                 "keymapping removed invalid keycode entry %s pointing to more than one modifier (%s): %s",
                 keycode, mods, entries)
             continue
         #now remove entries for keysyms we don't have:
         f_entries = set([(keysym, index) for keysym, index in entries
                          if parse_keysym(keysym) is not None])
         if len(f_entries) == 0:
             log(
                 "keymapping removed invalid keycode entry %s pointing to only unknown keysyms: %s",
                 keycode, entries)
             continue
         filtered[keycode] = f_entries
     return filtered
Example #4
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
        for name, index in entries:
            assert 0<=index and index<keysyms_per_keycode
            names[index] = name
            try:
                keysym = parse_keysym(name)
            except:
                keysym = None
            if keysym is None:
                if name!="":
                    missing_keysyms.append(name)
            else:
                if keysyms[index] is not None:
                    log.warn("we already have a keysym for %s at index %s: %s, entries=%s", server_keycode, index, keysyms[index], entries)
                else:
                    keysyms[index] = keysym
        #remove empty keysyms:
        while len(keysyms)>0 and keysyms[0] is None:
            keysyms = keysyms[1:]
        debug("%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))
    debug("instructions=%s", instructions)
    return  instructions
Example #5
0
def set_keycodes(keycodes, preserve_keycodes={}):
    """
        The keycodes given may not match the range that the server supports,
        so we return a translation map for those keycodes that have been
        remapped.
        The preserve_keycodes is a dict containing {keysym:keycode}
        for keys we want to preserve the keycode for.
    """
    kcmin,kcmax = get_minmax_keycodes()
    free_keycodes = []
    for i in range(kcmin, kcmax):
        if i not in keycodes.keys() and i not in preserve_keycodes.values():
            free_keycodes.append(i)
    log.debug("set_keycodes(..) min=%s, max=%s, free_keycodes=%s", kcmin, kcmax, free_keycodes)

    used = []
    trans = {}
    instructions = []
    for keycode, entries in keycodes.items():
        server_keycode = keycode
        if preserve_keycodes:
            for entry in entries:
                (_, name, _, group, level) = entry
                if group==0 and level==0 and name in preserve_keycodes:
                    server_keycode = preserve_keycodes.get(name)
                    if server_keycode!=keycode:
                        log.debug("set_keycodes key %s(%s) mapped to keycode=%s", keycode, entries, server_keycode)
        if server_keycode==0 or server_keycode in used or server_keycode<kcmin or server_keycode>kcmax:
            if len(free_keycodes)>0:
                server_keycode = free_keycodes[0]
                free_keycodes = free_keycodes[1:]
                log.debug("set_keycodes key %s(%s) out of range or already in use, using free keycode=%s", keycode, entries, server_keycode)
            else:
                log.error("set_keycodes: no free keycodes!, cannot translate %s: %s", keycode, entries)
                continue
        if server_keycode!=keycode and keycode!=0:
            trans[keycode] = server_keycode
        used.append(server_keycode)
        keysyms = []
        #sort them by group then level
        def sort_key(entry):
            (_, _, _, group, level) = entry
            return group*10+level
        sentries = sorted(entries, key=sort_key)
        for (_, name, _keycode, _, _) in sentries:
            assert _keycode == keycode
            keysym = parse_keysym(name)
            if keysym is None:
                log.error("cannot find keysym for %s", name)
            else:
                keysyms.append(keysym)
        if len(keysyms)>=2 and len(keysyms)<=6:
            keysyms = keysyms[:2]+keysyms
        if len(keysyms)>0:
            instructions.append(("keycode", server_keycode, keysyms))
    log.debug("instructions=%s", instructions)
    unset = apply_xmodmap(instructions)
    log.debug("unset=%s", unset)
    log.debug("translated keycodes=%s", trans)
    log.debug("%s free keycodes=%s", len(free_keycodes), free_keycodes)
    return  trans
Example #6
0
def set_keycodes(keycodes, preserve_keycodes={}):
    """
        The keycodes given may not match the range that the server supports,
        so we return a translation map for those keycodes that have been
        remapped.
        The preserve_keycodes is a dict containing {keysym:keycode}
        for keys we want to preserve the keycode for.
    """
    kcmin, kcmax = get_minmax_keycodes()
    free_keycodes = []
    for i in range(kcmin, kcmax):
        if i not in keycodes.keys() and i not in preserve_keycodes.values():
            free_keycodes.append(i)
    log.debug("set_keycodes(..) min=%s, max=%s, free_keycodes=%s", kcmin,
              kcmax, free_keycodes)

    used = []
    trans = {}
    instructions = []
    for keycode, entries in keycodes.items():
        server_keycode = keycode
        if preserve_keycodes:
            for entry in entries:
                (_, name, _, group, level) = entry
                if group == 0 and level == 0 and name in preserve_keycodes:
                    server_keycode = preserve_keycodes.get(name)
                    if server_keycode != keycode:
                        log.debug(
                            "set_keycodes key %s(%s) mapped to keycode=%s",
                            keycode, entries, server_keycode)
        if server_keycode == 0 or server_keycode in used or server_keycode < kcmin or server_keycode > kcmax:
            if len(free_keycodes) > 0:
                server_keycode = free_keycodes[0]
                free_keycodes = free_keycodes[1:]
                log.debug(
                    "set_keycodes key %s(%s) out of range or already in use, using free keycode=%s",
                    keycode, entries, server_keycode)
            else:
                log.error(
                    "set_keycodes: no free keycodes!, cannot translate %s: %s",
                    keycode, entries)
                continue
        if server_keycode != keycode and keycode != 0:
            trans[keycode] = server_keycode
        used.append(server_keycode)
        keysyms = []

        #sort them by group then level
        def sort_key(entry):
            (_, _, _, group, level) = entry
            return group * 10 + level

        sentries = sorted(entries, key=sort_key)
        for (_, name, _keycode, _, _) in sentries:
            assert _keycode == keycode
            try:
                keysym = parse_keysym(name)
            except:
                keysym = None
            if keysym is None:
                log.error("cannot find keysym for %s", name)
            else:
                keysyms.append(keysym)
        if len(keysyms) >= 2 and len(keysyms) <= 6:
            keysyms = keysyms[:2] + keysyms
        if len(keysyms) > 0:
            instructions.append(("keycode", server_keycode, keysyms))
    log.debug("instructions=%s", instructions)
    unset = apply_xmodmap(instructions)
    log.debug("unset=%s", unset)
    log.debug("translated keycodes=%s", trans)
    log.debug("%s free keycodes=%s", len(free_keycodes), free_keycodes)
    return trans