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
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
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
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
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
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