keymapper-0.5.3.orig/0000775000000000000000000000000010223220737014411 5ustar rootroot00000000000000keymapper-0.5.3.orig/setup.py0000644000000000000000000000140010200103333016077 0ustar rootroot00000000000000#!/usr/bin/env python """Setup script for 'yapps'""" from distutils.core import setup description = "Keyboard mapping generator" long_description = \ """ This program generates a keyboard decision tree from a number of keyboard map files. """ setup (name = "keymapper", version = "0.2", description = description, long_description = long_description, author = "Matthias Urlichs", author_email = "smurf@smurf.noris.de", maintainer = "Matthias Urlichs", maintainer_email = "smurf@smurf.noris.de", url = "http://smurf.noris.de/code/", license = 'GPL', platforms = ['POSIX'], keywords = ['Keymap'], packages = ['keymapper','keymapper.parse'], scripts = ['gen_keymap'], ) keymapper-0.5.3.orig/gen_keymap0000644000000000000000000000700410200103332016434 0ustar rootroot00000000000000#!/usr/bin/python # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ This test script grabs a number of interesting key maps from keymapper.fakemaps, generates a decision tree, saves that in an in-memory file, and then runs each key map against the file's interpreter to see if the correct map is returned. """ from keymapper.parse.maps import parse_map,EmptyMapError,MapInputError from keymapper.tree import Tree, gen_report import keymapper.tree from keymapper.file import FileReporter from keymapper.graph import GraphReporter from keymapper.script import Script from keymapper.fakequery import FakeQuery from keymapper.parse.linux import parse_file as parse_linux from keymapper.parse.linux import FileProblem import sys import codecs from optparse import OptionParser, OptParseError from subprocess import Popen,PIPE try: from cStringIO import StringIO except ImportError: from StringIO import StringIO parser = OptionParser(usage="%prog list...", version="%prog 0.1") parser.remove_option("-h") #parser.remove_option("--help") parser.add_option("-?","--help", action="help", help="show this help text") parser.add_option("-v","--verbose", action="count", dest="verbose", help="be more verbose") parser.add_option("-m","--minlen", action="store", dest="minlen", type="int", default=30, help="Too-short Keymaps are skipped (default: 30 entries)") parser.add_option("-g","--graph", action="store_const", dest="format", const="graphviz", help="generate a hopefully-nice-looking .dot file") parser.add_option("--maps", action="store_const", dest="format", const="mapdump", help="print the to-be-processed keymaps") parser.add_option("-o","--output", action="store", dest="filename", help="output file (default: stdout)") (opts, args) = parser.parse_args() if not args: parser.error("no arguments supplied") sys.exit(1) t = Tree() keymapper.tree.trace = opts.verbose if opts.filename: out=open(opts.filename,"w") else: out=sys.stdout if opts.format == "graphviz": out = codecs.getwriter("latin1")(out,"replace") else: out = codecs.getwriter("utf-8")(out) for f in args: for l in open(f): comment = l.find('#') if comment > -1: l = l[:comment] l = l.strip() if l == "": continue if " " in l or "\t" in l: (name,code) = l.split() else: name = l code = "utf-8" # code = codecs.getreader(code) # pipe = Popen(("loadkeys","-q","-M",name), stdout=PIPE).stdout # pipe = code(pipe) try: if opts.verbose: print "Parsing:",name # map = parse_map(name,pipe) map = parse_linux(name) except EmptyMapError: print >>sys.stderr,"Map '%s' skipped: empty" % name except MapInputError,exc: n,l,p = exc.args print >>sys.stderr,"Map '%s' skipped: data format error at %d:%d" % (n,l,p) except UnicodeDecodeError: print >>sys.stderr,"Map '%s' skipped: codec error" % name except FileProblem,e: print >>sys.stderr,"... skipped '%s'" % e.args else: if opts.minlen > len(map): print >>sys.stderr,"... skipped '%s': only %d keys" % (map,len(map)) continue; if opts.format == "mapdump": print >>out,map.dump() else: t.add(map) if opts.format == "mapdump": sys.exit(0) t.gen_tree() if opts.format == "graphviz": gen_report(t,GraphReporter(out)) else: gen_report(t,FileReporter(out)) # done! keymapper-0.5.3.orig/keymapper/0000775000000000000000000000000010223220737016406 5ustar rootroot00000000000000keymapper-0.5.3.orig/keymapper/parse/0000775000000000000000000000000010223220737017520 5ustar rootroot00000000000000keymapper-0.5.3.orig/keymapper/parse/__init__.py0000644000000000000000000000004110200103333021605 0ustar rootroot00000000000000 # yet another almost-empty file keymapper-0.5.3.orig/keymapper/parse/maps.py0000644000000000000000000000314710200103333021020 0ustar rootroot00000000000000 # maps.py # read keyboard maps # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ This module exports 'maps()', which is a function that returns a list of keyboard maps with various interesting features. Among the tested variants are: - addditional key, key missing - swapped keys - relabeled keys - totally different keys - totally different keycodes """ from keymapper.keymap import Keymap,STD,SHIFT,ALT,ALTSHIFT import re class MapInputError(RuntimeError): pass class EmptyMapError(RuntimeError): pass num=re.compile(r'^(\d+)') word=re.compile(r'^(\S+)') names={"plain":STD, "shift":SHIFT, "altgr":ALT, "shift_altgr":ALTSHIFT, "shift_alt":ALTSHIFT,"altgr_alt":ALT,"alt":ALT,"shift_altgr_alt":ALTSHIFT} def parse_map(name,f): """read a Keymap""" map=Keymap(name) l = f.read() if not l: raise EmptyMapError(name) line=1 pos=1 while l: m = num.match(l) if not m: raise MapInputError(name,line,pos) code = int(m.group(0)) l = l[m.end(0)+1:] pos += m.end(0)+1 m = word.match(l) while m: mod = m.group(0) sym = l[m.end(0)+1] end = l[m.end(0)+2] l = l[m.end(0)+3:] pos += m.end(0)+3 try: map.add(sym,code,names[mod]) except KeyError: print "Modifier '%s' unknown" % (mod,) pass if end == "\n": break m = word.match(l) line += 1 pos = 1 return map keymapper-0.5.3.orig/keymapper/parse/linuxsyms.py0000644000000000000000000000272410200103333022133 0ustar rootroot00000000000000 # keymapper/parse/linuxsyms.py # translate symbols to unicode (and back) # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """ translate symbols to unicode (and back). """ symfile = "data/symbols" map = {} alias = {} class RecursiveAlias(Exception): pass class SymbolNotFound(Exception): pass def read_table(): """Read the table of symbols""" f = open(symfile) for l in f: l = l.strip() comment = l.find('#') if comment > -1: l = l[:comment] l = l.strip() if l == "": continue if l[0] == "=": a,n = l[2:].split() if n in alias: raise RecursiveAlias(n) if a in map: raise RecursiveAlias(a) alias[a] = n elif l[0] == "-": for n in l[2:].split(): map[n] = "" else: # assume keysym c,n = l.split(None,1) c = eval("0x"+c,{},{}) c = eval("u'\\u%04x'" % c, {},{}) for nn in n.split(): map[nn] = c def lookup_symbol(name): """Translate name => unicode""" if not map: read_table() # print name, # XXX TODO: return that stuff somehow? if name.startswith("Meta_"): name = name[5:] while name in alias: name = alias[name] try: s = map[name] # print s return s except KeyError: raise SymbolNotFound(name) keymapper-0.5.3.orig/keymapper/parse/linux.g0000644000000000000000000001720310174511211021023 0ustar rootroot00000000000000""" This code implements a parser for Linux keyboard maps. """ from keymapper.parse.linuxsyms import lookup_symbol,SymbolNotFound from os.path import exists,join from gzip import GzipFile from keymapper.keymap import Keymap,Modifier import os dirs = [ # ".", "/usr/share/keymaps/i386/azerty", "/usr/share/keymaps/i386/dvorak", "/usr/share/keymaps/i386/fgGIod", "/usr/share/keymaps/i386/qwerty", "/usr/share/keymaps/i386/qwertz", "/usr/share/keymaps/i386/include", "/usr/share/keymaps/include" ] class NoFileFound(Exception): pass class FileProblem(Exception): pass class TooManySyms(Exception): pass def get_file(name): """Find a keymap file""" for end in ("",".kmap",".kmap.gz",".inc",".inc.gz", ".gz"): for dir in dirs: n = os.path.join(dir,name+end) if exists(n): if n.endswith(".gz"): f = GzipFile(n,"rb") else: f = open(n,"r") return f raise NoFileFound(name) class ConsoleKeymap(Keymap): """submap with interesting features for generating Linux console maps""" def __init__(self,*a,**k): Keymap.__init__(self,*a,**k) self.map_vector = [] def add_map_vector(self,a,b=None): """add to the list of keymaps""" if b is None: b=a self.map_vector.append((a,b)) def get_map_vector(self): v = self.map_vector if not v: v = ((0,255),) for a,b in v: for i in range(a,b+1): yield Modifier(bits=i) def compose(self,c1,c2,result): pass def add_more(self, rvalue, code, keys): try: keys = keys.next() except StopIteration: raise TooManySyms(code,rvalue) else: # print rvalue, code, keys self.add(rvalue, code, keys) def parse_file(name): f = get_file(name) keymap = ConsoleKeymap(name) parser = linuxmap(linuxmapScanner("",file=f,filename=name)) try: parser.map(keymap) except SymbolNotFound,e: print >>sys.stderr, "Keysym '%s' not found" % e.args print >>sys.stderr, parser._scanner raise FileProblem(name) except runtime.SyntaxError, e: runtime.print_error(e, parser._scanner, max_ctx=1) raise FileProblem(name) except runtime.NoMoreTokens: print >>sys.stderr, 'Could not complete parsing; stopped around here:' print >>sys.stderr, parser._scanner raise FileProblem(name) return keymap %% parser linuxmap: ignore: "[ \r\t]+" ignore: "\\\\\\n" ignore: "(#|!).*" token EOF: "$" token EOL: "\n" token BLANK: "[ \t]" token INCLUDE: "include[ \t]*" token _DECIMAL: "[1-9][0-9]*" token _OCTAL: "0[0-7]*" token _HEX: "0[xX][0-9a-fA-F]+" token _UNICODE: "U\\+([0-9a-fA-F]){4}" token LITERAL: "[a-zA-Z][a-zA-Z_0-9]*" token OCTA: "([0-7]){1,3}" token CHARSET: "charset|Charset|CharSet|CHARSET" token KEYMAPS: "keymaps|Keymaps|KeyMaps|KEYMAPS" token KEYCODE: "keycode|Keycode|KeyCode|KEYCODE" token STRING: "string|String|STRING" token EQUALS: "=" token COMMA: "," token PLAIN: "plain|Plain|PLAIN" token SHIFT: "shift|Shift|SHIFT" token CONTROL: "control|Control|CONTROL" token ALT: "alt|Alt|ALT" token ALTGR: "altgr|Altgr|AltGr|ALTGR" token SHIFTL: "shiftl|ShiftL|SHIFTL" token SHIFTR: "shiftr|ShiftR|SHIFTR" token CTRLL: "ctrll|CtrlL|CTRLL" token CTRLR: "ctrlr|CtrlR|CTRLR" token ALT_IS_META: "[aA][lL][tT][-_][iI][sS][-_][mM][eE][tT][aA]" token STRINGS: "strings|Strings|STRINGS" token COMPOSE: "compose|Compose|COMPOSE" token AS: "as|As|AS" token USUAL: "usual|Usual|USUAL" token FOR: "for|For|FOR" token ON: "on|On|ON" token TO: "to|To|TO" token _CHAR1: "'([0-7]){1,3}'" token _CHAR2: "'\\\\.'" token _CHAR3: "'.'" token PLUS: "\\+" token _STRLITERAL: '\'([^\\n\'\\\\]|\\\\.)*\'|"([^\\n"\\\\]|\\\\.)*"' rule DECIMAL: _DECIMAL {{ return int(_DECIMAL) }} rule OCTAL: _OCTAL {{ return eval(_OCTAL,{},{}) }} rule HEX: _HEX {{ return eval(_HEX,{},{}) }} rule UNICODE: _UNICODE {{ return eval("u'\\u%s'" % _UNICODE[2:],{},{}) }} rule CCHAR: _CHAR1 {{ return eval(_CHAR1,{},{}) }} | _CHAR2 {{ return _CHAR2[2] }} | _CHAR3 {{ return _CHAR3[1] }} rule NUMBER: DECIMAL {{ return DECIMAL }} | OCTAL {{ return OCTAL }} | HEX {{ return HEX }} rule STRLITERAL: _STRLITERAL {{ return eval(_STRLITERAL,{},{}) }} rule map<>: {{ self.data = data }} line* EOF rule line : EOL | charsetline | altismetaline | usualstringsline | keymapline | fullline | singleline | strline | compline | include rule include: "include" STRLITERAL {{ self._scanner.stack_input(file=get_file(STRLITERAL), filename=STRLITERAL) }} rule charsetline : CHARSET STRLITERAL EOL # { # set_charset(kbs_buf.kb_string); # } rule altismetaline : ALT_IS_META EOL # { # alt_is_meta = 1; # } rule usualstringsline: STRINGS AS USUAL EOL # { # strings_as_usual(); # } rule compline: COMPOSE ( usualcomposeline | composeline ) rule usualcomposeline: AS USUAL ( FOR STRLITERAL ) ? EOL # { # compose_as_usual(kbs_buf.kb_string); # } # | COMPOSE AS USUAL EOL # { # compose_as_usual(0); # } # { # keymaps_line_seen = 1; # } rule keymapline : KEYMAPS range ( COMMA range )* rule range : NUMBER {{ n1 = NUMBER }} ( "-" NUMBER {{ self.data.add_map_vector(n1,NUMBER) }} | {{ self.data.add_map_vector(n1) }} ) # { # int i; # for (i = $1; i<= $3; i++) # addmap(i,1); # } # | NUMBER # { # addmap($1,1); # } rule strline : STRING LITERAL EQUALS STRLITERAL EOL # { # if (KTYP($2) != KT_FN) # lkfatal1("'%s' is not a function key symbol", # syms[KTYP($2)].table[KVAL($2)]); # kbs_buf.kb_func = KVAL($2); # addfunc(kbs_buf); # } rule composeline : CCHAR {{ c1 = CCHAR }} CCHAR {{ c2 = CCHAR }} TO ( CCHAR {{ self.data.compose(c1, c2, CCHAR); }} | rvalue {{ self.data.compose(c1, c2, rvalue); }} ) EOL rule singleline : {{ mods = 0; }} modifiers KEYCODE NUMBER EQUALS rvalue EOL {{ self.data.add(rvalue, NUMBER, Modifier(modifiers)); }} | PLAIN KEYCODE NUMBER EQUALS rvalue EOL {{ self.data.add(rvalue, NUMBER, Modifier(())); }} rule modifiers : {{ vals = [] }} modifier<>+ {{ return vals }} rule modifier<> : mod {{ vals.append(mod) }} rule mod: SHIFT {{ return "shift" }} | CONTROL {{ return "control" }} | ALT {{ return "alt" }} | ALTGR {{ return "altgr" }} | SHIFTL {{ return "shiftL" }} | SHIFTR {{ return "shiftR" }} | CTRLL {{ return "controlL" }} | CTRLR {{ return "controlR" }} rule fullline: KEYCODE NUMBER EQUALS rvalue0<> EOL # { # int i, j; # # if (rvalct == 1) { # /* Some files do not have a keymaps line, and # we have to wait until all input has been read # before we know which maps to fill. */ # key_is_constant[$2] = 1; # # /* On the other hand, we now have include files, # and it should be possible to override lines # from an include file. So, kill old defs. */ # for (j = 0; j < max_keymap; j++) # if (defining[j]) # killkey($2, j); # } # if (keymaps_line_seen) { # i = 0; # for (j = 0; j < max_keymap; j++) # if (defining[j]) { # if (rvalct != 1 || i == 0) # addkey($2, j, (i < rvalct) ? key_buf[i] : K_HOLE); # i++; # } # if (i < rvalct) # lkfatal0("too many (%d) entries on one line", rvalct); # } else # for (i = 0; i < rvalct; i++) # addkey($2, i, key_buf[i]); # } rule rvalue0<>: {{ keys = self.data.get_map_vector() }} ( rvalue {{ self.data.add_more(rvalue, code, keys) }} )* rule rvalue: rvalue2 {{ return rvalue2 }} | PLUS rvalue2 {{ return rvalue2 }} ## TODO: caps lock rule rvalue2: NUMBER {{ return eval("u'\\u%04x'" % NUMBER, {},{}) }} | UNICODE {{ return UNICODE }} | LITERAL {{ return lookup_symbol(LITERAL) }} # | UNUMBER # {{ $$=add_number($1); }} %% keymapper-0.5.3.orig/keymapper/parse/Makefile0000644000000000000000000000015710174511211021154 0ustar rootroot00000000000000# Makefile for keymapper stuff # all: ${addsuffix .py, ${basename ${wildcard *.g}, .g}} %.py: %.g yapps $< keymapper-0.5.3.orig/keymapper/script.py0000644000000000000000000000556410200103333020257 0ustar rootroot00000000000000 # script.py # Runs a selection script # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ The Script class encapsulates the interpreter for the keymap selection script generated by FileReporter. The .run method will either return the keymap's name, or an error exception will be raised. """ class FoundMap(Exception): """Pseudo-exception, raised when the script terminates with a unique keyboard map""" pass class UnknownLine(Exception): """The script file contains a line that's not parseable""" pass class BadFile(Exception): """The script file isn't well-formed""" pass class Script(object): """Run this script with that query. Return the result.""" def __init__(self,file,query): self.file = file self.in_step = -1 self.query = query def get_step(self,nr): """Return the data for step NR.""" for f in self.file: f = f.strip() if f == "" or f.startswith("#"): continue if f.startswith("STEP"): f = f[4:] f = int(f.strip()) if self.in_step == nr: # done self.in_step = f return self.in_step = f elif self.in_step == nr: yield f # ran off the end of the file? if nr != self.in_step: raise BadFile def run_step(self,step): """Run a singe step. Returns the next step's number, or raise an exception.""" what = None syms = [] keys = {} # First, collect the data for line in self.get_step(step): if line.startswith("PRESS") and what in (None,"press"): what="press" syms.append(line[5:].strip()) elif line.startswith("CODE") and what in (None,"press"): what="press" code,goal = line[4:].strip().split() keys[int(code)] = int(goal) elif line.startswith("MAP") and what in (None,): raise FoundMap(line[3:].strip()) elif line.startswith("FIND") and what in (None,): what="find1" find = line[4:].strip() elif line.startswith("YES") and what in ("find1",): what="find2" dest_yes = int(line[3:].strip()) elif line.startswith("NO") and what in ("find2",): what="find3" dest_no = int(line[4:].strip()) else: raise UnknownLine(line.strip()) # Second, decide what to do if what == "press" and syms and keys: while True: code = self.query.press(syms) if code in keys: return keys[code] self.query.message("Unexpected key code: <%d>" % code) elif what == "find3": if self.query.ask(find): return dest_yes else: return dest_no else: raise BadFile def run(self): """Run this script, starting with step 0.""" step=0 while True: try: step = self.run_step(step) except FoundMap,exc: return exc.args[0] keymapper-0.5.3.orig/keymapper/keymap.py0000644000000000000000000001055710200103333020237 0ustar rootroot00000000000000 # keymap.py # represent a key map # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ This module contains the 'Keymap' class, which represents a particular keyboard mapping. """ from sets import ImmutableSet # This code implements a bitmask and associated bit values. modlist=("shift","altgr","control","alt","shiftl","shiftr","controll","controlr","capsshift") bitmods={} modmods={} modbits={} n=1 for f in modlist: modbits[f] = n n = n*2 del n del modlist class Modifier(object): """Encapsulate shift/alt/control/... state""" def __str__(self): if self.mods: return "+".join(self.mods) else: return "plain" def __repr__(self): return "M<%s>" % (self.__str__(),) def _calc_prio(self): """Figure out the priority of a modifier""" if not self.mods: return 100 if len(self.mods) == 1 and "shift" in self.mods: return 0 pri=0 mods=self.mods for mod,val in (("altgr",500),("alt",1000),("control",1500)): if mod in self.mods: pri -= val mods = mods-ImmutableSet(mod) if "shift" in mods: pri *= 1.5 mods = mods-ImmutableSet("shift") pri *= 1+(len(mods)/3) return pri def _get_prio(self): """read the priority""" if not hasattr(self,"_prio"): self._prio = self._calc_prio() return self._prio pri = property(_get_prio) def __new__(cls,mods=None,bits=None): """Return an existing modifier (pseudo-Singleton)""" if bits is None: if mods is None: raise NameError elif mods is not None: raise NameError else: try: return bitmods[bits] except KeyError: # not found: calculate modifier list mods=[] for f,n in modbits.items(): if bits & n: mods.append(f) mods = ImmutableSet(mods) try: return modmods[mods] except KeyError: m = object.__new__(cls) if bits is None: bits = 0 for mod in mods: bits |= modbits[mod.lower()] m.bits = bits m.mods = mods modmods[mods] = m bitmods[bits] = m return m def __init__(self,*a,**k): pass STD=Modifier(mods=()) SHIFT=Modifier(mods=("shift",)) ALT=Modifier(mods=("alt",)) ALTSHIFT=Modifier(mods=("alt","shift")) #class CodeKnown(Exception): # """Trying to add a code+modifier entry to a keymap that's already known""" # pass class Keymap(object): """encapsulates a named symbol <=> keycode+modifiers mapping""" def __init__(self,name): self.name = name self.sym2code = {} # sym => (code,modifier) list self.sym2cod = {} # sym => code list # self.code2sym = {} # <= self.submap_cache = {} def __str__(self): return "Map<%s>" % (self.name,) __repr__=__str__ def __len__(self): return len(self.sym2cod) def add(self,sym,code,mod=STD): """add a single key mapping to this keymap""" if sym == "": return if sym in self.sym2cod: if code not in self.sym2cod[sym]: self.sym2cod[sym].append(code) else: self.sym2cod[sym] = [code] code = (code,mod) if sym in self.sym2code: if code not in self.sym2code[sym]: self.sym2code[sym].append(code) return # if code in self.code2sym: # raise CodeKnown(self.name,code) self.sym2code[sym] = [code] # self.code2sym[code] = sym def symbols(self): """Return a list of known symbols""" return self.sym2code.iterkeys() def priority(self,sym): """Return how likely it is that this symbol is actually shown on the physical keyboard""" if not self.sym2code[sym]: pass return reduce(max, [ k[1].pri for k in self.sym2code[sym] ]) def dump(self): """Show my mapping""" return self.name+": "+",".join([ "%s:%s" % (self.vis(s), "+".join([str(x) for x in c])) for s,c in self.sym2cod.items()]) def vis(self,s): if len(s) == 1 and ord(s) < 128: return repr(s)[1:] else: return "'"+s+"'" def is_submap(self,m): """Check if self is a submap of m.""" try: return self.submap_cache[m] except KeyError: for s,cs in self.sym2cod.items(): if s not in m.sym2cod: self.submap_cache[m] = False return False cm = m.sym2cod[s] for c in cs: if c not in cm: self.submap_cache[m] = False return False self.submap_cache[m] = True print "%s is a submap of %s" % (self,m) return True keymapper-0.5.3.orig/keymapper/fakemaps.py0000644000000000000000000000400410200103332020525 0ustar rootroot00000000000000 # fakemaps.py # invent fake keyboard maps for testing # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ This module exports 'maps()', which is a function that returns a list of keyboard maps with various interesting features. Among the tested variants are: - addditional key, key missing - swapped keys - relabeled keys - totally different keys - totally different keycodes """ from keymapper.keymap import Keymap,STD,SHIFT,ALT def gen_map(name,*keys): """synthesize a Keymap""" map=Keymap(name) for sym,code,mod in keys: map.add(sym,code,mod) return map def maps(): """return a list of nicely incompatible keyboards""" yield gen_map("std", ("A",1,STD),("B",2,STD),("C",3,STD),("D",4,STD),("E",5,STD)) # Swap two keys yield gen_map("swapped", ("B",1,STD),("A",2,STD),("C",3,STD),("D",4,STD),("E",5,STD)) # Remove a key yield gen_map("removed", ("A",1,STD),("B",2,STD),("C",3,STD),("D",4,STD)) # Duplicate a key yield gen_map("duped", ("A",1,STD),("B",2,STD),("C",3,STD),("A",4,STD)) # Add a new key yield gen_map("add_new", ("A",1,STD),("B",2,STD),("C",3,STD),("D",4,STD),("E",5,STD),("G",11,STD)) # Add a key we know from somewhere yield gen_map("add_known", ("A",1,STD),("B",2,STD),("C",3,STD),("D",4,STD),("E",5,STD),("F",7,STD)) # Relabel a key yield gen_map("relabel", ("A",1,STD),("B",2,STD),("C",3,STD),("D",4,STD),("F",5,STD)) # Totally different keys yield gen_map("diff_keys", ("a",1,STD),("b",2,STD),("c",3,STD),("d",4,STD),("e",5,STD)) # Totally different codes yield gen_map("diff_codes", ("A",6,STD),("B",7,STD),("C",8,STD),("D",9,STD),("F",10,STD)) # Small keyboard ;-) yield gen_map("small", ("A",1,STD),("B",1,SHIFT),("C",1,ALT),("D",2,STD),("E",2,ALT)) keymapper-0.5.3.orig/keymapper/graph.py0000644000000000000000000000437610200103332020053 0ustar rootroot00000000000000 # graph.py # write a decision tree to a file, graphviz .dot format # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ This module prints a decision tree, by writing all the steps to a file. """ from keymapper.tree import Reporter import sys import unicodedata def uname(sym): try: return unicodedata.name(unicode(sym)).lower() except ValueError: return "U+%4x" % ord(sym) def symnums(syms): return ".".join([str(ord(s)) for s in syms]) class GraphReporter(Reporter): """Report the result as a graphviz .dot file""" def __init__(self,file=sys.stdout): self.file = file def init(self): print >>self.file, "digraph keyboard_tree {" def exit(self): print >>self.file, "}" def step(self,stepnr): """Start a new step""" self.nr = stepnr def keymap(self,map): """This steps selects a unique keymap""" print >>self.file, '"Step %d" [label="Map: %s"]' % (self.nr,map.name) def symbols(self,symbols): """Start a choice: display these symbols""" self.syms = symbols def choice(self,code,nextstep): """Choice: This keycode leads to that step""" syms=[] for s,c in self.syms.items(): if code in c: syms.append(s) print >>self.file, '"Step %d" -> "S_%d_%s_%d"' % (self.nr,self.nr, symnums(syms), code) print >>self.file, '"S_%d_%s_%d" -> "Step %d"' % (self.nr,symnums(syms), code, nextstep.step) print >>self.file, '"S_%d_%s_%d" [ label="%s -> %d" ]' % (self.nr, symnums(syms), code, "\\n".join([uname(s) for s in syms]), code) def ask(self,sym,no,yes): """Ask whether that symbol is visible""" print >>self.file, '"Step %d" [ label="Step %d\\nCheck for %s" ]' % (self.nr,self.nr,uname(sym)) print >>self.file, '"Step %d" -> "AY-%d" -> "Step %d"' % (self.nr,self.nr,yes.step) print >>self.file, '"AY-%d" [ label="Yes" ]' % (self.nr,) print >>self.file, '"Step %d" -> "AN-%d" -> "Step %d"' % (self.nr,self.nr,no.step) print >>self.file, '"AN-%d" [ label="No" ]' % (self.nr,) def finish(self): """Conclude this step""" pass keymapper-0.5.3.orig/keymapper/fakequery.py0000644000000000000000000000232510200103332020736 0ustar rootroot00000000000000 # fakequery.py # answer a question by looking at a keymap # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ This module answers questions by looking them up in the supplied keymap. """ from keymapper.query import Query from random import uniform class FakeQuery(Query): """A fake keyboard inquiry which actually looks at a keymap. Used for testing.""" def __init__(self, map): Query.__init__(self) self.map = map def press(self,syms): print "* Press one of '"+"' '".join(syms)+"' !" syms = [ sym for sym in syms if sym in self.map.sym2code ] print "I have '"+"' '".join(syms)+"'." sym = syms[int(uniform(0,len(syms)))] code = self.map.sym2code[sym] code = code[int(uniform(0,len(code)))][0] print "I choose %s => %d" % (sym,code) return code def ask(self,sym): print "* Do I see '"+sym+"' ?" if sym in self.map.sym2code: print "Yes" else: print "No" return sym in self.map.sym2code keymapper-0.5.3.orig/keymapper/tree.py0000644000000000000000000004246410200103333017712 0ustar rootroot00000000000000 # tree.py # represent a decision tree to decide between key maps # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ This code examines a list of keyboard maps and generates a decision tree which distinguishes between them in as few steps a possible. => class Tree The resulting tree has redundant nodes. As it makes sense to keep file sizes down, the redundant nodes are eliminated by turning the tree into a directed acyclic graph. => Node.simplify(). The graph is then traversed in depth-first order, except that entries which are referred to multiple times are processed only after their last parent has been processed. => Node.seq*(). This traversal generates a list of steps, all of which only refer to steps following them. A program which processed that list thus does not need to save any state between steps. """ from sets import Set,ImmutableSet # follow what's happening? trace=False last_trace=0 from time import time class DupKeycode(Exception): """A key code has been added to a Choice node twice""" pass class AlgorithmProblem(Exception): """The symbol selector was unable to find a solution""" pass class Reporter(object): """The interface for the output of the resulting decision tree""" def init(self): """Do preprocessing""" pass def exit(self): """Do postprocessing""" pass def step(self,stepnr): """Start a new step""" pass def keymap(self,map): """This steps selects a unique keymap""" raise NotImplementedError def symbols(self,symbols): """Start a choice: display these symbols""" raise NotImplementedError def choice(self,code,nextstep): """Choice: This keycode leads to that step""" raise NotImplementedError def ask(self,sym,no,yes): """Ask whether that symbol is visible""" raise NotImplementedError def finish(self): """Conclude this step""" pass def gen_report(tree,reporter): """Generate a report""" reporter.init() tree.report(reporter) reporter.exit() class Node(object): """a generic node in the keymap decision tree""" def __init__(self): self.delay = 0 def __eq__(self,other): """Compare this node to another""" if self.__class__ is not other.__class__: return False return True def __ne__(self,other): """Compare this node to another""" return not self.__eq__(other) def simplify(self,cache): """Check whether this node is redundant""" self = self._simplify(cache) key = self.key() if key in cache: return cache[key] cache[key] = self return self def report(self,gen): """Emit this node""" raise NotImplementedError def children(self): """Iterates over this node's immediate children""" raise StopIteration def key(self): """Return a string declaring this operation""" raise NotImplementedError def __str__(self): try: return "<"+self.key()+">" except NotImplementedError: object.__str__(self) # Serialize this tree. We walk it twice, counting the number of # parents. The first pass increments a counter and numbers the # nodes. The second pass decrements and prints when a node is # visited for the last time. # # Usage: tree.seq1(0) # for node in tree.seq2(): # do_something_with(node) def seq1(self,nr): """Serialization, step 1: number nodes and count the parents""" # print "K %02d: %s :: %s" % (nr,repr(self),str(self)) self.delay += 1 if self.delay > 1: return nr self.step = nr nr += 1 for c in self: # iterates the children nr = c.seq1(nr) self.maxstep = nr return nr def seq2(self): """Serialization, step 2: iterate over this node, if visited from its last parent""" # print "N %02d/%02d: %s :: %s" % (self.step,self.delay,repr(self),str(self)) if not self.delay: raise AssertionError("called seq2() before calling seq1()") self.delay -= 1 if self.delay: return yield self for c in self: # iterates over child nodes for n in c.seq2(): yield n class Choice(Node): """a node in the keymap decision tree which asks for one of a number of symbols and selects by the keycode that's returned""" def __init__(self, sym2codes, code2map): Node.__init__(self) self.sym2codes = sym2codes # list of symbols to display => key codes self.children = code2map # key code => node or keymap def __iter__(self): return self.children.itervalues() def __eq__(self,other): if not Node.__eq__(self,other): return False if len(self.sym2codes) != len(other.sym2codes): return False if len(self.children) != len(other.children): return False for sym in self.sym2codes: if sym not in other.sym2codes: return False for code,node in self.children.items(): if code not in other.children: return False if node != other.children[code]: return False return True def __ne__(self,other): return not self.__eq__(other) def key(self): syms = [ sym for sym in self.sym2codes ] syms.sort() ret = "Q:"+":".join(self.sym2codes.keys())+":" codes = self.children.keys() codes.sort() for code in codes: ret += "%d<%s>" % (code,self.children[code].key()) return ret def _simplify(self,cache): """Try to make this node smaller""" for code,node in self.children.items(): if node: node = node.simplify(cache) if node: self.children[code] = node else: del self.children[code] # Throw this node away if it doesn't decide anything any more uniq = None for child in self.children.values(): if not uniq: uniq = child elif uniq != child: return self return uniq def report(self,gen): gen.step(self.step) gen.symbols(self.sym2codes) for code,node in self.children.items(): gen.choice(code,node) gen.finish() class Ask(Node): """a node in the keymap decision tree which asks whether a given keyboard symbol exists""" def __init__(self, sym,no,yes): Node.__init__(self) self.sym = sym self.no = no self.yes = yes def __iter__(self): yield self.no yield self.yes def key(self): return "S%s<%s><%s>" % (self.sym,self.yes.key(),self.no.key()) def __eq__(self,other): if not Node.__eq__(self,other): return False if self.sym != other.sym: return False if self.yes != other.yes: return False if self.no != other.no: return False return True def _simplify(self,cache): if self.yes: self.yes = self.yes.simplify(cache) if self.no: self.no = self.no.simplify(cache) if self.yes == self.no: return self.yes if self.yes and self.no: return self if self.no: return self.no return self.yes def report(self,gen): gen.step(self.step) gen.ask(self.sym, self.no, self.yes) gen.finish() class Found(Node): """A node which resolves to a single keymap""" def __init__(self, node): Node.__init__(self) self.node = node def __iter__(self): return ().__iter__() def __eq__(self,other): if not Node.__eq__(self,other): return False if self.node != other.node: return False return True def _simplify(self,cache): if self.node is None: return None return self def report(self,gen): gen.step(self.step) gen.keymap(self.node) gen.finish() def key(self): return "M<%s>" % self.node.name # Special exceptions for signalling that there's no possible choice. class NoMapping(Exception): pass class SingleMapping(Exception): pass # The main code starts here. class Tree(object): """encapsulates a keymap decision tree.""" def __init__(self): self.maps=Set() # list of keyboards self.symbols={} # symbol => [nummaps,sumpriority] self._id = 0 def add(self,map): """add a keymap to the list""" self.maps.add(map) def gen_tree(self): """generate a decision tree""" cache={} self.tree = self._gen_tree(self.maps) self.tree = self.tree.simplify(cache) def report(self,gen): """Emit the generated nodes by passing them to a generator.""" self.tree.seq1(0) for n in self.tree.seq2(): n.report(gen) def _gen_tree(self, maps, xsyms=None): """One step of the selection algorithm.""" if not len(maps): return None if len(maps) == 1: # This construct simply extracts the one set member ... return Found([m for m in maps][0]) _id = self._id self._id += 1 if not xsyms: xsyms = ImmutableSet() # major speed-up: find the set of symbols which don't make a difference xsyms = drop_sym(maps,xsyms) syms = ImmutableSet() # selected symbols codes = {} # keycode => number of selected keymaps for alt in range(2): # Try to get one alternate mapping if trace>1: if alt: print "*** Alternate:",syms else: print "*** Start:",_id,len(maps),"maps:",",".join([m.name for m in maps]) try: open_map = ImmutableSet(maps) track = [] # List of backtracking iterators and the environment they # need to choose from. Backtracking is necessary because # a selection might exhaust all possible keymaps except # for one which happens to be a subset of another. chooser=None while open_map: if not chooser: global last_trace if trace>2 or trace and time()-last_trace > 3 and len(open_map)>2: print "choose from",",".join([m.name for m in open_map]) last_trace=time() chooser = choose_sym(open_map, syms.union(xsyms), xcode=codes, all_maps=maps, alt=alt) while True: # Loop invariant: # open_map contains the keymaps for which we # need to find a symbol selecting from them. # syms: the keys selecting from maps no longer in open_map # codes: the possible keycodes of these syms # => the list of maps they might refer to. try: if trace>2: print "track len", len(track), sym,do_single = chooser.next() except StopIteration: # This chooser is unable to return a # suitable choice, so backtrack. if trace>1: print "exhausted",",".join([m.name for m in open_map]) if not track: raise AlgorithmProblem(syms,maps,open_map) chooser,syms,codes,open_map = track.pop() if trace>1: print "... back to",",".join([m.name for m in open_map]) except AlgorithmProblem: raise AlgorithmProblem(syms,maps,open_map) else: if trace>2: print "got",sym.encode("utf-8"), # We have a possible candidate. try: # Get the list of keymaps chosen by it map_no = sym2maps(sym,maps,do_single) if trace>2: print "OK, no_map",",".join([m.name for m in map_no]) break except NoMapping: # Try again / backtrack if this symbol # doesn't actually affect our current # choices. if trace>2: print "no mapping" continue except SingleMapping,exc: # This is a possible yes/no question. # If that's the best we can do, OK. map_yes,map_no = exc.args if trace>2: print "single mapping: yes",len(map_yes),"no",len(map_no) if not track: return Ask(sym, yes=self._gen_tree(map_yes), no=self._gen_tree(map_no)) # Otherwise, try to add the symbol's # code as-is, assuming that it helps. if map_yes & open_map: break continue new_codes=dict(codes) # shallow copy broken=False for map in maps: if broken: break if sym in map.sym2code: for cd in map.sym2cod[sym]: new_codes[cd] = 1 + new_codes.get(cd,0) if new_codes[cd] == len(maps): # This keycode now selects from all the # keymaps, which is not helpful -- prssing # that key would give us the whole # map again => endless loop. broken=True break if broken: if alt: # If we just try to get a redundant mapping, # end the process here. break # Otherwise, try again / backtrack. if trace>2: print "no go" continue # remember the track.append((chooser,syms,codes,open_map)) codes = new_codes open_map &= map_no syms |= ImmutableSet((sym,)) chooser = None except AlgorithmProblem,exc: # We get here if there's no possible choice. if alt: # If we already have a completed pass through the # list, that doesn't matter. break (syms,maps,open_map) = exc.args import sys print >>sys.stderr, "These keymaps appear to be indistinguishable:", ",".join([m.name for m in open_map]) if trace: for m in open_map: print >>sys.stderr, m.dump().encode("utf-8") sys.exit(1) # Now build a Choice node from what we have found. data={} codes = {} sym2codes = {} for sym in syms: if sym not in sym2codes: sym2codes[sym]=[] for map in maps: if sym not in map.sym2cod: continue for code in map.sym2cod[sym]: if code not in codes: codes[code] = Set() codes[code].add(map) if code not in sym2codes[sym]: sym2codes[sym].append(code) if trace>1: print "***",_id for code,map in codes.items(): print code,map print "*** end ***",_id,len(maps),"***", \ " ".join(["%s:%s" % (s,",".join([str(cc) for cc in c])) for s,c in sym2codes.items()]).encode("utf-8") print for code,map in codes.items(): codes[code] = self._gen_tree(map) ch = Choice(sym2codes, codes) return ch def choose_sym(maps, xsym=(), xcode=(), all_maps=(), alt=0): """Find the 'best' symbol in a set of keymaps""" symdata={} # symbol => [ preference, number of keymaps with that symbol, # mapping keycode => number of keyboards with that mapping # If any of these maps is a subset of one of all_maps, drop out. # Reason: We can't put up a "do you have this key" question now. for m in maps: for am in all_maps: if am not in maps and m.is_submap(am): return for map in maps: for sym in map.symbols(): if sym in xsym: continue if sym not in symdata: symdata[sym] = [ 0, 0, {} ] data = symdata[sym] # Heuristic: We try to block keys on ALT mappings, which # have values smaller than zero, by never raising the value # if it ever goes below zero pri = map.priority(sym) # if data[0] >= 0: # if pri is None: # pass # data[0] += pri # if pri >= 0 and data[0] < 0: # data[0] = 0 # else: # if pri < 0: # data[0] += pri if ord(sym) > 0x40 and ord(sym) <= 0x5a: if alt: pri += 300 else: pri += 5000 elif ord(sym) > 0x60 and ord(sym) <= 0x7a: if alt: pri += 300 else: pri += 5000 elif ord(sym) > 128: pri += 800 elif ord(sym) < 32 or ord(sym) == 127: pri += -300 else: if alt: pri += 600 else: pri += 1000 data[0] += pri for code in map.sym2cod[sym]: # This check must not be done here. # It blocks the "raise AlgorithmProblem" later if we # have two maps A:sym=(code1,code2) and B:sym=(code1) # and code1 is in xcodes. # if code in xcode: continue if code not in data[2]: data[2][code] = 0 data[1] += 1 data[2][code] += 1 syms=[] xxsyms=Set() for sym,(pri,sum,codes) in symdata.iteritems(): if not codes.values(): continue # if len([v for v in codes.values() if v == len(maps)]): # continue for c in codes: if c in xcode: xxsyms.add(sym) break # This is the max number of keymaps which have that symbol # on the same key. maxcodes = reduce(max,[ num for num in codes.values() ]) nfull=0 for map in all_maps: if sym in map.sym2code: nfull += 1 # more heuristics: # Prefer symbols that appear in all maps. # Prefer symbols that don't appear in maps we already selected. # Prefer symbols that appear in many keyboards. # Prefer symbols which result in many small subtrees, # i.e. the number of maps having that symbol on the same # keycode is small. #pri -= 100*(len(maps)-sum) pri -= 500*(nfull-sum) pri += 100*len(codes) pri -= 500*maxcodes syms.append((-pri,sym)) if len(maps) > 1 and not syms: raise AlgorithmProblem syms.sort() # print # print syms # for m in maps: # print m.dump().encode("utf-8") # print # First, generate normal "press a key" choices. for pri,sym in syms: if sym not in xxsyms: if trace>2: print "check",sym.encode("utf-8"), yield sym,False # If that didn't work, use excluded keycodes if not alt: for pri,sym in syms: if sym in xxsyms: if trace>2: print "check",sym.encode("utf-8"), yield sym,False # If that didn't work, generate yes/no questions. for pri,sym in syms: if symdata[sym][1] < len(maps): # ... but only if there are keyboards for which the answer is 'no'. yield sym,True def drop_sym(maps, xsym): """Find those symbol in a set of keymaps""" return xsym def sym2maps(sym,maps,choose): """Returns a list keycode => maps with the symbol on that key""" codes = Set() xmaps = Set() altmaps = Set() for map in maps: if not sym in map.sym2code: xmaps.add(map) continue for code,pri in map.sym2code[sym]: codes.add(code) if pri < 0: altmaps.add(code) # If there's less than two choices, return via an exception. if len(codes) == 0: raise NoMapping(sym) if len(codes) == 1: if not xmaps: raise NoMapping(sym) if choose: raise SingleMapping(maps-xmaps, xmaps) # If the symbol occurs with normal AND AltGr mappings, # ignore the AltGr stuff -- the symbol may not actually be # printed on the key... if xmaps > altmaps: xmaps -= altmaps return xmaps keymapper-0.5.3.orig/keymapper/file.py0000644000000000000000000000256410200103332017666 0ustar rootroot00000000000000 # file.py # write a decision tree to a file, evaluation format # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ This module prints a decision tree, by writing all the steps to a file. """ from keymapper.tree import Reporter import sys class FileReporter(Reporter): """Report the result as a list of steps to a file""" def __init__(self,file=sys.stdout): self.file = file def step(self,stepnr): """Start a new step""" print >>self.file,"STEP %d" % stepnr def keymap(self,map): """This steps selects a unique keymap""" print >>self.file,"MAP %s" % map.name def symbols(self,symbols): """Start a choice: display these symbols""" for sym in symbols: print >>self.file,"PRESS %s" % sym def choice(self,code,nextstep): """Choice: This keycode leads to that step""" print >>self.file,"CODE %d %d" % (code,nextstep.step) def ask(self,sym,no,yes): """Ask whether that symbol is visible""" print >>self.file,"FIND %s" % sym print >>self.file,"YES %s" % yes.step print >>self.file,"NO %s" % no.step def finish(self): """Conclude this step""" pass keymapper-0.5.3.orig/keymapper/query.py0000644000000000000000000000234210200103333020107 0ustar rootroot00000000000000 # query.py # Abstract class for answering inquiries # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ Interface description for asking he user about a keyboard. We ask two kinds of questions: - Press any one of [list of symbols]! The keyboard is expected to have at least one of them. "None of the above" is not an acceptable answer. - Does your keyboard show [symbol]? The user can answer "yes" or "no". """ class Query(object): """A keyboard inquiry. Presumably we need to switch the keyboard to raw mode or something.""" def __init__(self): pass def start(self): """Startup the questions.""" pass def press(self,syms): """Ask the user to press one of these keys""" raise NotImplementedError def ask(self,sym): """Ask the user if this key exists""" raise NotImplementedError def message(self, msg): """Tell the user something.""" print msg def done(self): """Shutdown the questions.""" pass keymapper-0.5.3.orig/keymapper/__init__.py0000644000000000000000000000005110162573327020521 0ustar rootroot00000000000000 # empty ## except for this comment ;-) keymapper-0.5.3.orig/COPYING.txt0000644000000000000000000004311010200103333016242 0ustar rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. keymapper-0.5.3.orig/debian/0000775000000000000000000000000010223220737015633 5ustar rootroot00000000000000keymapper-0.5.3.orig/debian/changelog0000644000000000000000000000061710200103332017471 0ustar rootroot00000000000000keymapper (0.2-1) unstable; urgency=low * Works, for now. * Optionally generates graphviz output. * Added installation and copyright stuff. -- Matthias Urlichs Wed, 2 Feb 2005 08:34:28 +0100 keymapper (0.1-1) unstable; urgency=low * Initial Release. (Doesn't do anything useful yet...) -- Matthias Urlichs Thu, 23 Dec 2004 18:44:42 +0100 keymapper-0.5.3.orig/debian/control0000644000000000000000000000124410174511211017230 0ustar rootroot00000000000000Source: keymapper Section: utils Priority: optional Maintainer: Matthias Urlichs Build-Depends: debhelper (>= 4.1) Standards-Version: 3.6.1 Build-Depends: yapps2, python (>= 2.4) Package: keymapper Architecture: any Depends: ${misc:Depends}, ${python:Depends}, yapps2-runtime (>= 2.1.1-17) Suggests: graphviz Description: Keyboard map decision tree builder and interpreter This package implements an alternate way to let a user decide which keyboard map to use. It generates a decision tree and then asks the user to press a couple of keys. Depending on which keycode is returned, the list of possible keyboards is pruned until there is only one left. keymapper-0.5.3.orig/debian/copyright0000644000000000000000000000057410162603163017572 0ustar rootroot00000000000000This package was written by Matthias Urlichs , starting on Thu, 23 Dec 2004. Copyright: (C) 2004, Matthias Urlichs . This code is released under the terms of the GNU General Public License version 2. On Debian(-derived) systems, the complete text of the GNU General Public License can be found in the file '/usr/share/common-licenses/GPL' keymapper-0.5.3.orig/debian/docs0000644000000000000000000000000710162603163016501 0ustar rootroot00000000000000README keymapper-0.5.3.orig/debian/dirs0000644000000000000000000000001010162603163016504 0ustar rootroot00000000000000usr/bin keymapper-0.5.3.orig/debian/rules0000755000000000000000000000275610162603163016723 0ustar rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 CFLAGS = -Wall -g ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O0 else CFLAGS += -O2 endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. python setup.py build touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp test -f changelog || bk changes > changelog dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs python setup.py install --root=$(shell pwd)/debian/keymapper --no-compile --install-purelib=/usr/lib/site-python # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot dh_installchangelogs dh_installdocs find debian/*/usr/share -name SCCS -print0 | xargs -0r rm -rf dh_compress dh_fixperms # dh_perl dh_python # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure keymapper-0.5.3.orig/debian/compat0000644000000000000000000000000210162603163017027 0ustar rootroot000000000000004 keymapper-0.5.3.orig/test_gen_map.py0000644000000000000000000000302610200103333017412 0ustar rootroot00000000000000#!/usr/bin/python # Copyright (c) 2005 by Matthias Urlichs # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. See the file COPYING.txt # or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. """\ This test script grabs a number of interesting key maps from keymapper.fakemaps, generates a decision tree, saves that in an in-memory file, and then runs each key map against the file's interpreter to see if the correct map is returned. """ from keymapper.fakemaps import maps from keymapper.tree import Tree, gen_report from keymapper.file import FileReporter from keymapper.graph import GraphReporter from keymapper.script import Script from keymapper.fakequery import FakeQuery import sys try: from cStringIO import StringIO except ImportError: from StringIO import StringIO keymaps = [] t = Tree() for k in maps(): t.add(k) keymaps.append(k) t.gen_tree() buf = StringIO() gen_report(t,FileReporter(buf)) g = open("test.dot","w") gen_report(t,GraphReporter(g)) # 'buf' now contains our script. buf.seek(0,0) print buf.read(), err = 0 for k in keymaps: buf.seek(0,0) print "Testing keymap %s" % (k.dump(),) s = Script(buf,FakeQuery(k)) name = s.run() if name != k.name: print "SCRIPT ERROR: %s != %s" % (name,k.name) err += 1 else: print "... OK." print if err: print "%d errors found!" % err sys.exit(1) else: print "Everything works." sys.exit(0) keymapper-0.5.3.orig/README0000644000000000000000000001342610200103231015255 0ustar rootroot00000000000000========= Keymapper ========= The Problem =========== Keyboard selection is a problem for many users since most ofthem have no idea which keyboard layout they have. This program uses a different approach. We simply ask the user to press a couple of keys and infer from their scan code which layout they belong to, thereby lowering the number of possibilities in a classic divide-and-conquer approach. Some difficulties show up. For instance, asking people to press a key they don't have is considered to be bad style. Todistinguish between German and Danish keyboards, we therefore have to offer multiple possible symbols. This should also be helpful with trying to distinguish between QWERTZ and AZERTY when the user has a cyrillic keyboard. :-) Inferring the decision tree from a large number of keyboard layouts is not efficient, thus the tree neds to be pre-calculated. There are two ways of selecting among possible layouts: * Ask the user to press a key with a particular symbol * Ask the user to choose the symbol which appears on a key, e.g. to the right of the tab key. This tool will only use the first approach. If it is not possible to distinguish between keyboard layouts that way, e.g. because their only difference is whether a particular key has an X or a Y symbol, a simple binary question ("Do you have an X key") may have to be asked. Basic selection algorithm ========================= Initially, list all keyboards. Create a list of forbidden scan codes, which is initially empty. Select a symbol that appears on most keyboards, in as many places as possible, but not on any keys in the forbidden list. Remoce these keyboards from the keyboard list and add the scan codes of those keys to the forbidden list. Repeat until the list of keyboards is empty. Display the list of symbols to the user. Each scan code we get back is associated with at least one keyboard. Clear the list of scan codes and repeat this process if there is more than one. Heuristics ---------- Unmodified, this method tends to pick 'obscure' keys like @, which tend to be in lots of different places historically. Unfortunately, the risk of this approach is that people will not find the key if it's not labelled as such on their keyboard. Some possible modifications are: * Initially, prefer ASCII letters and low-ASCII symbols. * Strongly prefer a symbol that's not selected with AltGr or, less strongly, Shift (unless the base key is a number). Especially in the former case, the symbol may not even appear on the keyboard. (DONE) (partly conflicts with the first part) * In order to avoid an "I can't find any of these keys" problem, it might be necessary to prepare two symbol lists in each step. The key codes should be distinct of course. (DONE) * Some key choices should be either avoided or combined. For instance, asking the user to press an A in order to find out whether the layout is French (qwerty vs. azerty) might be a bad idea if Cyrillic keyboards have not been either excluded (in a previous question) or included (by internally mapping а => a, ѡ => ω, etc., and accepting all ppossible answers). A list of Unicode glyph lookalikes should be findable on the Internet. In addition, it might make sense to always show capital letters. (TODO) * Do a global optimization to minimize tree depth. Currently, key selection locally favors deciding between many layouts with one symbol -- the problem is that the keys which end up selecting between the rest also select from a few of those already decided on by the first ones, thus they add more steps. A nicer strategy might be to find a group of symbols which collecively do the same thing, only better. Tests ===== Testing this approach is the easiest part of the problem -- the FakeQuery class answers the questions depending on which keyboard map was passed to it. If multiple answers are possible, one is selected randomly. Redundancy ---------- During twenty test runs with the nine initiall test keymaps, the system asked 27 questions on average, or three per keymap. Since 2^3 is 8, the generated decision tree is shorter than a binary tree, which suggests that generating two symbol lists in parallel doesn't result in asking additional questions. Graph output ------------ Since the result is somewhat difficult to visualize, I added graphviz output. The result isn't pretty in any way (specifically, edge labels are not placed correctly) but it's a workable first step. File output ----------- The data file produced by this tool consists of a number of lines: STEP ## +++++++ This line starts a new step. Steps are numbered; the first step is numbered zero. Steps are not necessarily numbered consecutively, but all references pint to steps which occur later in the file. Thus it is never necessary to keep the while file in memory. MAP name ++++++++ This step uniquely identifies a keymap. The MAP command is the only command in is step. PRESS char ++++++++++ Ask the user to press a character on the keyboard. Multiple PRESS commands may occur in a step; the characters (encoded in utf-8) need to be presented simultaneously ("Press one of these keys"). Auxiliary keys (shift, alt, ...) should be ignored. CODE code ## ++++++++++++ Direct the evaluating code to process step ## next if the user has pressed a key which returned that keycode. Obviously, multiple CODE commands may occur in a step. FIND char +++++++++ Ask the user whether that character is present on their keyboard. This is a question of last resort; it's asked only if keymaps cannot be distinguished otherwise. This command will be accompanied by one YES and one GOTO command. YES ## ++++++ Direct the evaluating code to process step ## next if the user does have this key. NO ## +++++ Direct the evaluating code to process step ## next if the user does not have this key. keymapper-0.5.3.orig/data/0000775000000000000000000000000010223220737015322 5ustar rootroot00000000000000keymapper-0.5.3.orig/data/symbols0000644000000000000000000003260610174511211016735 0ustar rootroot000000000000000000 nul 0001 Control_a 0002 Control_b 0003 Control_c 0004 Control_d 0005 Control_e 0006 Control_f 0007 Control_g 0008 BackSpace 0009 Tab 000a Linefeed 000b Control_k 000c Control_l 000d Control_m 000e Control_n 000f Control_o 0010 Control_p 0011 Control_q 0012 Control_r 0013 Control_s 0014 Control_t 0015 Control_u 0016 Control_v 0017 Control_w 0018 Control_x 0019 Control_y 001a Control_z 001b Escape 001c Control_backslash 001d Control_bracketright 001e Control_asciicircum 001f Control_underscore 0020 space 0021 exclam 0022 quotedbl 0023 numbersign 0024 dollar 0025 percent 0026 ampersand 0027 apostrophe 0028 parenleft 0029 parenright 002a asterisk 002b plus 002c comma 002d minus 002e period 002f slash 0030 zero 0031 one 0032 two 0033 three 0034 four 0035 five 0036 six 0037 seven 0038 eight 0039 nine 003a colon 003b semicolon 003c less 003d equal 003e greater 003f question 0040 at 0041 A 0042 B 0043 C 0044 D 0045 E 0046 F 0047 G 0048 H 0049 I 004a J 004b K 004c L 004d M 004e N 004f O 0050 P 0051 Q 0052 R 0053 S 0054 T 0055 U 0056 V 0057 W 0058 X 0059 Y 005a Z 005b bracketleft 005c backslash 005d bracketright 005e asciicircum dead_circumflex 005f underscore 0060 grave dead_grave 0061 a 0062 b 0063 c 0064 d 0065 e 0066 f 0067 g 0068 h 0069 i 006a j 006b k 006c l 006d m 006e n 006f o 0070 p 0071 q 0072 r 0073 s 0074 t 0075 u 0076 v 0077 w 0078 x 0079 y 007a z 007b braceleft 007c bar 007d braceright 007e asciitilde dead_tilde 007f Delete 00a0 nobreakspace 00a0 no-break_space 00a1 exclamdown 00a2 cent 00a3 sterling 00a4 currency 00a5 yen 00a6 brokenbar 00a7 paragraph_sign 00a7 section 00a8 diaeresis dead_diaeresis 00a9 copyright 00aa ordfeminine 00ab guillemotleft 00ac notsign 00ad hyphen 00ad soft_hyphen 00ae registered 00af macron 00b0 degree 00b1 plusminus 00b2 twosuperior 00b3 threesuperior 00b4 acute dead_acute 00b5 mu 00b6 paragraph 00b7 periodcentered 00b8 cedilla dead_cedilla 00b9 onesuperior 00ba masculine 00bb guillemotright 00bb rightanglequote 00bc onequarter 00bd onehalf 00be threequarters 00bf questiondown 00c0 Agrave 00c1 Aacute 00c2 Acircumflex 00c3 Atilde 00c4 Adiaeresis 00c5 Aring 00c6 AE 00c7 Ccedilla 00c8 Egrave 00c9 Eacute 00ca Ecircumflex 00cb Ediaeresis 00cc Igrave 00cd Iacute 00ce Icircumflex 00cf Idiaeresis 00d0 ETH 00d1 Ntilde 00d2 Ograve 00d3 Oacute 00d4 Ocircumflex 00d5 Otilde 00d6 Odiaeresis 00d7 multiplication 00d7 multiply 00d8 Ooblique 00d9 Ugrave 00da Uacute 00db Ucircumflex 00dc Udiaeresis 00dd Yacute 00de THORN 00df ssharp 00e0 agrave 00e1 aacute 00e2 acircumflex 00e3 atilde 00e4 adiaeresis 00e5 aring 00e6 ae 00e7 ccedilla 00e8 egrave 00e9 eacute 00ea ecircumflex 00eb ediaeresis 00ec igrave 00ed iacute 00ee icircumflex 00ef idiaeresis 00f0 eth 00f1 ntilde 00f2 ograve 00f3 oacute 00f4 ocircumflex 00f5 otilde 00f6 odiaeresis 00f7 division 00f8 oslash 00f9 ugrave 00fa uacute 00fb ucircumflex 00fc udiaeresis 00fd yacute 00fe thorn 00ff ydiaeresis 0100 Amacron 0101 amacron 0102 Abreve 0103 abreve 0104 Aogonek 0105 aogonek 0106 Cacute 0107 cacute 0108 Ccircumflex 0109 ccircumflex 010a Cabovedot 010b cabovedot 010c Ccaron 010d ccaron 010e Dcaron 010f dcaron 0110 Dstroke 0111 dstroke 0112 Emacron 0113 emacron 0116 Eabovedot 0117 eabovedot 0118 Eogonek 0119 eogonek 011a Ecaron 011b ecaron 011c Gcircumflex 011d gcircumflex 011e Gbreve 011f gbreve 0120 Gabovedot 0121 gabovedot 0122 Gcedilla 0123 gcedilla 0124 Hcircumflex 0125 hcircumflex 0126 Hstroke 0127 hstroke 0128 Itilde 0129 itilde 012a Imacron 012b imacron 012e Iogonek 012f iogonek 0130 Iabovedot 0131 idotless 0134 Jcircumflex 0135 jcircumflex 0136 Kcedilla 0137 kcedilla 0138 kra 0139 Lacute 013a lacute 013b Lcedilla 013c lcedilla 013d Lcaron 013e lcaron 0141 Lstroke 0142 lstroke 0143 Nacute 0144 nacute 0145 Ncedilla 0146 ncedilla 0147 Ncaron 0148 ncaron 014a ENG 014b eng 014c Omacron 014d omacron 0150 Odoubleacute 0151 odoubleacute 0152 OE 0153 oe 0154 Racute 0155 racute 0156 Rcedilla 0157 rcedilla 0158 Rcaron 0159 rcaron 015a Sacute 015b sacute 015c Scircumflex 015d scircumflex 015e Scedilla 015f scedilla 0160 Scaron 0161 scaron 0162 Tcedilla 0163 tcedilla 0164 Tcaron 0165 tcaron 0166 Tslash 0167 tslash 0168 Utilde 0169 utilde 016a Umacron 016b umacron 016c Ubreve 016d ubreve 016e Uring 016f uring 0170 Udoubleacute 0171 udoubleacute 0172 Uogonek 0173 uogonek 0178 Ydiaeresis 0179 Zacute 017a zacute 017b Zabovedot 017c zabovedot 017d Zcaron 017e zcaron 02bc rightquote 02bd leftquote 02c7 caron 02d8 breve 02d9 abovedot 02db ogonek 02dd doubleacute 0384 accent 0385 diaeresisaccent 0386 Alphaaccent 0388 Epsilonaccent 0389 Etaaccent 038a Iotaaccent 038c Omicronaccent 038e Upsilonaccent 038f Omegaaccent 0390 iotadiaeresisaccent 0391 Alpha 0392 Beta 0393 Gamma 0394 Delta 0395 Epsilon 0396 Zeta 0397 Eta 0398 Theta 0399 Iota 039a Kappa 039b Lamda 039c Mu 039d Nu 039e Ksi 039f Omicron 03a0 Pi 03a1 Rho 03a3 Sigma 03a4 Tau 03a5 Upsilon 03a6 Phi 03a7 Khi 03a8 Psi 03a9 Omega 03aa Iotadiaeresis 03ab Upsilondiaeresis 03ac alphaaccent 03ad epsilonaccent 03ae etaaccent 03af iotaaccent 03b0 upsilondiaeresisaccent 03b1 alpha 03b2 beta 03b3 gamma 03b4 delta 03b5 epsilon 03b6 zeta 03b7 eta 03b8 theta 03b9 iota 03ba kappa 03bb lamda 03bc mu 03bd nu 03be ksi 03bf omicron 03c0 pi 03c1 rho 03c2 terminalsigma 03c3 sigma 03c4 tau 03c5 upsilon 03c6 phi 03c7 khi 03c8 psi 03c9 omega 03ca iotadiaeresis 03cb upsilondiaeresis 03cc omicronaccent 03cd upsilonaccent 03ce omegaaccent 0401 cyrillic_capital_letter_io 0402 serbocroatian_cyrillic_capital_letter_dje 0403 macedonian_cyrillic_capital_letter_gje 0404 ukrainian_cyrillic_capital_letter_ie 0405 macedonian_cyrillic_capital_letter_dze 0406 ukrainian_cyrillic_capital_letter_i 0407 ukrainian_cyrillic_capital_letter_yi 0408 cyrillic_capital_letter_je 0409 cyrillic_capital_letter_lje 040a cyrillic_capital_letter_nje 040b serbocroatian_cyrillic_capital_letter_chje 040c macedonian_cyrillic_capital_letter_kje 040e bielorussian_cyrillic_capital_letter_short_u 040f cyrillic_capital_letter_dze 0410 cyrillic_capital_letter_a 0411 cyrillic_capital_letter_be 0412 cyrillic_capital_letter_ve 0413 cyrillic_capital_letter_ghe 0414 cyrillic_capital_letter_de 0415 cyrillic_capital_letter_ie 0416 cyrillic_capital_letter_zhe 0417 cyrillic_capital_letter_ze 0418 cyrillic_capital_letter_i 0419 cyrillic_capital_letter_short_i 041a cyrillic_capital_letter_ka 041b cyrillic_capital_letter_el 041c cyrillic_capital_letter_em 041d cyrillic_capital_letter_en 041e cyrillic_capital_letter_o 041f cyrillic_capital_letter_pe 0420 cyrillic_capital_letter_er 0421 cyrillic_capital_letter_es 0422 cyrillic_capital_letter_te 0423 cyrillic_capital_letter_u 0424 cyrillic_capital_letter_ef 0425 cyrillic_capital_letter_ha 0426 cyrillic_capital_letter_tse 0427 cyrillic_capital_letter_che 0428 cyrillic_capital_letter_sha 0429 cyrillic_capital_letter_shcha 042a cyrillic_capital_hard_sign 042b cyrillic_capital_letter_yeru 042c cyrillic_capital_soft_sign 042d cyrillic_capital_letter_e 042e cyrillic_capital_letter_yu 042f cyrillic_capital_letter_ya 0430 cyrillic_small_letter_a 0431 cyrillic_small_letter_be 0432 cyrillic_small_letter_ve 0433 cyrillic_small_letter_ghe 0434 cyrillic_small_letter_de 0435 cyrillic_small_letter_ie 0436 cyrillic_small_letter_zhe 0437 cyrillic_small_letter_ze 0438 cyrillic_small_letter_i 0439 cyrillic_small_letter_short_i 043a cyrillic_small_letter_ka 043b cyrillic_small_letter_el 043c cyrillic_small_letter_em 043d cyrillic_small_letter_en 043e cyrillic_small_letter_o 043f cyrillic_small_letter_pe 0440 cyrillic_small_letter_er 0441 cyrillic_small_letter_es 0442 cyrillic_small_letter_te 0443 cyrillic_small_letter_u 0444 cyrillic_small_letter_ef 0445 cyrillic_small_letter_ha 0446 cyrillic_small_letter_tse 0447 cyrillic_small_letter_che 0448 cyrillic_small_letter_sha 0449 cyrillic_small_letter_shcha 044a cyrillic_small_hard_sign 044b cyrillic_small_letter_yeru 044c cyrillic_small_soft_sign 044d cyrillic_small_letter_e 044e cyrillic_small_letter_yu 044f cyrillic_small_letter_ya 0451 cyrillic_small_letter_io 0452 serbocroatian_cyrillic_small_letter_dje 0453 macedonian_cyrillic_small_letter_gje 0454 ukrainian_cyrillic_small_letter_ie 0455 macedonian_cyrillic_small_letter_dze 0456 ukrainian_cyrillic_small_letter_i 0457 ukrainian_cyrillic_small_letter_yi 0458 cyrillic_small_letter_je 0459 cyrillic_small_letter_lje 045a cyrillic_small_letter_nje 045b serbocroatian_cyrillic_small_letter_chje 045c macedonian_cyrillic_small_letter_kje 045e bielorussian_cyrillic_small_letter_short_u 045f cyrillic_small_letter_dze 05d0 alef 05d1 bet 05d2 gimel 05d3 dalet 05d4 he 05d5 vav 05d6 zayin 05d7 het 05d8 tet 05d9 yod 05da finalkaf 05db kaf 05dc lamed 05dd finalmem 05de mem 05df finalnun 05e0 nun 05e1 samekh 05e2 ayin 05e3 finalpe 05e4 pe 05e5 finaltsadi 05e6 tsadi 05e7 qof 05e8 resh 05e9 shin 05ea tav 2017 doubleunderscore 201e quotedblbase 203e overscore 20ac euro 2116 number_acronym - F1 F2 F3 F4 F5 - F6 F7 F8 F9 F10 - F11 F12 F13 F14 F15 - F16 F17 F18 F19 F20 - Find - Insert - Remove - Select - Prior - Next - Macro - Help - Do - Pause - F21 F22 F23 F24 F25 - F26 F27 F28 F29 F30 - F31 F32 F33 F34 F35 - F36 F37 F38 F39 F40 - F41 F42 F43 F44 F45 - F46 F47 F48 F49 F50 - F51 F52 F53 F54 F55 - F56 F57 F58 F59 F60 - F61 F62 F63 F64 F65 - F66 F67 F68 F69 F70 - F71 F72 F73 F74 F75 - F76 F77 F78 F79 F80 - F81 F82 F83 F84 F85 - F86 F87 F88 F89 F90 - F91 F92 F93 F94 F95 - F96 F97 F98 F99 F100 - F101 F102 F103 F104 F105 - F106 F107 F108 F109 F110 - F111 F112 F113 F114 F115 - F116 F117 F118 F119 F120 - F121 F122 F123 F124 F125 - F126 F127 F128 F129 F130 - F131 F132 F133 F134 F135 - F136 F137 F138 F139 F140 - F141 F142 F143 F144 F145 - F146 F147 F148 F149 F150 - F151 F152 F153 F154 F155 - F156 F157 F158 F159 F160 - F161 F162 F163 F164 F165 - F166 F167 F168 F169 F170 - F171 F172 F173 F174 F175 - F176 F177 F178 F179 F180 - F181 F182 F183 F184 F185 - F186 F187 F188 F189 F190 - F191 F192 F193 F194 F195 - F196 F197 F198 F199 F200 - F201 F202 F203 F204 F205 - F206 F207 F208 F209 F210 - F211 F212 F213 F214 F215 - F216 F217 F218 F219 F220 - F221 F222 F223 F224 F225 - F226 F227 F228 F229 F230 - F231 F232 F233 F234 F235 - F236 F237 F238 F239 F240 - F241 F242 F243 F244 F245 - F246 - VoidSymbol - Return - Show_Registers - Show_Memory - Show_State - Break - Last_Console - Caps_Lock - Num_Lock - Scroll_Lock - Scroll_Forward - Scroll_Backward - Boot - Caps_On - Compose - SAK - Decr_Console - Incr_Console - KeyboardSignal - Bare_Num_Lock - KP_0 - KP_1 - KP_2 - KP_3 - KP_4 - KP_5 - KP_6 - KP_7 - KP_8 - KP_9 - KP_Add - KP_Subtract - KP_Multiply - KP_Divide - KP_Enter - KP_Comma - KP_Period - KP_MinPlus - Console_1 - Console_2 - Console_3 - Console_4 - Console_5 - Console_6 - Console_7 - Console_8 - Console_9 - Console_10 - Console_11 - Console_12 - Console_13 - Console_14 - Console_15 - Console_16 - Console_17 - Console_18 - Console_19 - Console_20 - Console_21 - Console_22 - Console_23 - Console_24 - Console_25 - Console_26 - Console_27 - Console_28 - Console_29 - Console_30 - Console_31 - Console_32 - Console_33 - Console_34 - Console_35 - Console_36 - Console_37 - Console_38 - Console_39 - Console_40 - Console_41 - Console_42 - Console_43 - Console_44 - Console_45 - Console_46 - Console_47 - Console_48 - Console_49 - Console_50 - Console_51 - Console_52 - Console_53 - Console_54 - Console_55 - Console_56 - Console_57 - Console_58 - Console_59 - Console_60 - Console_61 - Console_62 - Console_63 - Down - Left - Right - Up - Shift - AltGr - Control - Alt - ShiftL - ShiftR - CtrlL - CtrlR - CapsShift - Ascii_0 - Ascii_1 - Ascii_2 - Ascii_3 - Ascii_4 - Ascii_5 - Ascii_6 - Ascii_7 - Ascii_8 - Ascii_9 - Hex_0 - Hex_1 - Hex_2 - Hex_3 - Hex_4 - Hex_5 - Hex_6 - Hex_7 - Hex_8 - Hex_9 - Hex_A - Hex_B - Hex_C - Hex_D - Hex_E - Hex_F - Shift_Lock - AltGr_Lock - Control_Lock - Alt_Lock - ShiftL_Lock - ShiftR_Lock - CtrlL_Lock - CtrlR_Lock - SShift - SAltGr - SControl - SAlt - SShiftL - SShiftR - SCtrlL - SCtrlR = Control_h BackSpace = Control_i Tab = Control_j Linefeed = Home Find = End Select = PageUp Prior = PageDown Next = pound sterling = pilcrow paragraph = Oslash Ooblique = Shift_L ShiftL = Shift_R ShiftR = Control_L CtrlL = Control_R CtrlR = AltL Alt = AltR AltGr = Alt_L Alt = Alt_R AltGr = AltGr_L Alt = AltGr_R AltGr = AltLLock Alt_Lock = AltRLock AltGr_Lock = SCtrl SControl = Spawn_Console KeyboardSignal = Uncaps_Shift CapsShift = lambda lamda = Lambda Lamda = xi ksi = Xi Ksi = chi khi = Chi Khi = tilde asciitilde = circumflex asciicircum = dead_ogonek dead_cedilla = dead_caron dead_circumflex = dead_breve dead_tilde = dead_doubleacute dead_tilde = bielorussian_cyrillic_capital_letter_i ukrainian_cyrillic_capital_letter_i = cyrillic_capital_letter_kha cyrillic_capital_letter_ha = cyrillic_capital_letter_ge cyrillic_capital_letter_ghe = cyrillic_capital_letter_ia cyrillic_capital_letter_ya = cyrillic_capital_letter_iu cyrillic_capital_letter_yu = cyrillic_capital_letter_yeri cyrillic_capital_letter_yeru = cyrillic_capital_letter_reversed_e cyrillic_capital_letter_e = cyrillic_capital_letter_ii cyrillic_capital_letter_i = cyrillic_capital_letter_short_ii cyrillic_capital_letter_short_i = bielorussian_cyrillic_small_letter_i ukrainian_cyrillic_small_letter_i = cyrillic_small_letter_kha cyrillic_small_letter_ha = cyrillic_small_letter_ge cyrillic_small_letter_ghe = cyrillic_small_letter_ia cyrillic_small_letter_ya = cyrillic_small_letter_iu cyrillic_small_letter_yu = cyrillic_small_letter_yeri cyrillic_small_letter_yeru = cyrillic_small_letter_reversed_e cyrillic_small_letter_e = cyrillic_small_letter_ii cyrillic_small_letter_i = cyrillic_small_letter_short_ii cyrillic_small_letter_short_i = Idotabove Iabovedot = dotlessi idotless keymapper-0.5.3.orig/data/keymaps0000644000000000000000000000225610174511210016713 0ustar rootroot00000000000000lt fr latin1 be-latin1 latin1 dvorak-classic latin1 dvorak-fr latin1 pc-dvorak-latin1 latin1 trfu utf-8 ar bg cp1251 br-latin1 latin1 #by iso-8859-5 ## indistinguishable from gr cf iso-8859-15 cz-lat2 latin2 ## skip until we can decide on plain-vs-shift/alt stuff #cz-us-qwerty latin2 dk iso-8859-15 es iso-8859-15 et iso-8859-15 fa utf-8 fi iso-8859-15 fi-latin1 latin1 gr iso-8859-7 gr-pc iso-8859-7 gr-utf8 utf-8 hebrew iso-8859-8 hu101 iso-8859-2 #il-heb iso-8859-8 ## == il il iso-8859-8 #il-phonetic iso-8859-8 ## indistinguishable from hebrew is-latin1 #is-latin1-us it2 it-ibm #it #jp106 la-latin1 lk201-us #lt.l4 #lv-latin4 #lv-latin7 mk nl no no-latin1 no-standard pc110 #pl1 pl pt-latin1 pt-old ro #ru1 #ru2 #ru3 ru4 #ru-cp1251 ru #ru-ms ru_win ru-yawerty #se-fi-ir209 se-fi-lat6 #se-ir209 se-lat6 #se-latin1 sk-prog #sk-prog-qwerty sk-qwerty #sr-cy tralt trq trqu ua ua-utf #ua-utf-ws uaw #ua-ws uaw_uni uk us-latin1 latin1 # de-latin1 latin1 #de-latin1-nodeadkeys latin1 de latin1 #fr_CH #fr_CH-latin1 #hu #mac-usb-de_CH #mac-usb-de-latin1 #mac-usb-de-latin1-nodeadkeys #mac-usb-fr_CH-latin1 #mac-usb-pt-latin1 #sg #sg-latin1 #sg-latin1-lk450 #sk-prog-qwertz #sk-qwertz #slovene #sr keymapper-0.5.3.orig/Makefile0000644000000000000000000000013010174511211016034 0ustar rootroot00000000000000# Makefile for keymapper stuff compile: # python setup.py $(MAKE) -C keymapper/parse keymapper-0.5.3.orig/changelog0000644000000000000000000004210210223220737016260 0ustar rootroot00000000000000ChangeSet 1.19 05/02/02 08:54:14 smurf@smurf.noris.de +1 -0 ignore stuff BitKeeper/etc/ignore 1.10 05/02/02 08:53:31 smurf@smurf.noris.de +2 -0 added debian/*.debhelper debian/*.substvars BitKeeper/etc/ignore 1.9 05/02/02 08:53:09 smurf@smurf.noris.de +2 -0 added debian/keymapper/* build/* setup.py 1.1 05/02/02 08:52:59 smurf@smurf.noris.de +28 -0 COPYING.txt 1.1 05/02/02 08:52:59 smurf@smurf.noris.de +340 -0 ChangeSet 1.18 05/02/02 08:52:59 smurf@smurf.noris.de +16 -0 Add copyright stuff Rename program to "gen_keymap" Fix usage messages test_gen_map.py 1.5 05/02/02 08:52:59 smurf@smurf.noris.de +7 -0 add copyright setup.py 1.0 05/02/02 08:52:59 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/setup.py keymapper/tree.py 1.6 05/02/02 08:52:59 smurf@smurf.noris.de +7 -4 add copyright keymapper/script.py 1.4 05/02/02 08:52:59 smurf@smurf.noris.de +6 -2 add copyright keymapper/query.py 1.3 05/02/02 08:52:59 smurf@smurf.noris.de +6 -2 add copyright keymapper/parse/maps.py 1.8 05/02/02 08:52:59 smurf@smurf.noris.de +7 -2 add copyright keymapper/parse/linuxsyms.py 1.2 05/02/02 08:52:59 smurf@smurf.noris.de +10 -0 add copyright keymapper/parse/__init__.py 1.2 05/02/02 08:52:59 smurf@smurf.noris.de +2 -0 add copyright keymapper/keymap.py 1.7 05/02/02 08:52:59 smurf@smurf.noris.de +6 -2 add copyright COPYING.txt 1.0 05/02/02 08:52:59 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/COPYING.txt keymapper/graph.py 1.6 05/02/02 08:52:58 smurf@smurf.noris.de +8 -5 add copyright keymapper/file.py 1.4 05/02/02 08:52:58 smurf@smurf.noris.de +7 -4 add copyright keymapper/fakequery.py 1.4 05/02/02 08:52:58 smurf@smurf.noris.de +6 -2 add copyright keymapper/fakemaps.py 1.4 05/02/02 08:52:58 smurf@smurf.noris.de +7 -2 add copyright gen_keymap 1.10 05/02/02 08:52:58 smurf@smurf.noris.de +11 -4 add copyright debian/changelog 1.2 05/02/02 08:52:58 smurf@smurf.noris.de +8 -0 New version ChangeSet 1.17 05/02/02 08:51:53 smurf@smurf.noris.de +2 -0 more TODO README 1.6 05/02/02 08:51:53 smurf@smurf.noris.de +9 -2 more TODO stuff gen_keymap 1.9 05/02/02 08:51:14 smurf@smurf.noris.de +0 -0 Rename: gen_map -> gen_keymap gen_map 1.8 05/02/02 08:46:47 smurf@smurf.noris.de +0 -0 Rename: gen_map.py -> gen_map ChangeSet 1.16 05/01/25 23:14:03 smurf@smurf.noris.de +3 -0 Document the command file syntax. Replace GOTO with NO, as that expresses what's happening more clearly. keymapper/script.py 1.3 05/01/25 23:14:03 smurf@smurf.noris.de +1 -1 replace GOTO with NO keymapper/file.py 1.3 05/01/25 23:14:03 smurf@smurf.noris.de +1 -1 replace GOTO with NO README 1.5 05/01/25 23:14:03 smurf@smurf.noris.de +60 -0 document the command file ChangeSet 1.15 05/01/22 19:23:11 smurf@smurf.noris.de +1 -0 gone ?? BitKeeper/etc/gone 1.1 05/01/22 19:22:53 smurf@smurf.noris.de +1 -0 BitKeeper/etc/gone 1.0 05/01/22 19:22:53 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/BitKeeper/etc/gone ChangeSet 1.14 05/01/22 18:52:36 smurf@smurf.noris.de +1 -0 set logging field BitKeeper/etc/config 1.2 05/01/22 18:52:36 smurf@smurf.noris.de +1 -1 set logging field ChangeSet 1.13 05/01/22 18:52:01 smurf@smurf.noris.de +1 -0 ignore stuff BitKeeper/etc/ignore 1.8 05/01/22 18:51:51 smurf@smurf.noris.de +1 -0 added keymapper/parse/linux.py BitKeeper/etc/ignore 1.7 05/01/22 18:51:38 smurf@smurf.noris.de +2 -0 added foo foo? BitKeeper/etc/ignore 1.6 05/01/22 18:51:31 smurf@smurf.noris.de +1 -0 added dottybug.dot ChangeSet 1.12 05/01/22 18:51:06 smurf@smurf.noris.de +13 -0 Added our own keymap parser. Lots of bug fixes. keymapper/parse/linuxsyms.py 1.1 05/01/22 18:51:05 smurf@smurf.noris.de +63 -0 keymapper/parse/linux.g 1.1 05/01/22 18:51:05 smurf@smurf.noris.de +301 -0 keymapper/parse/__init__.py 1.1 05/01/22 18:51:05 smurf@smurf.noris.de +0 -0 keymapper/parse/Makefile 1.1 05/01/22 18:51:05 smurf@smurf.noris.de +8 -0 data/symbols 1.1 05/01/22 18:51:05 smurf@smurf.noris.de +816 -0 Makefile 1.1 05/01/22 18:51:05 smurf@smurf.noris.de +5 -0 keymapper/tree.py 1.5 05/01/22 18:51:05 smurf@smurf.noris.de +140 -43 lots of debugging change heuristics in the second pass add keycode-exclude processing back keymapper/parse/maps.py 1.7 05/01/22 18:51:05 smurf@smurf.noris.de +1 -1 added shift+altgr+alt keymapper/parse/linuxsyms.py 1.0 05/01/22 18:51:05 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/parse/linuxsyms.py keymapper/parse/linux.g 1.0 05/01/22 18:51:05 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/parse/linux.g keymapper/parse/__init__.py 1.0 05/01/22 18:51:05 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/parse/__init__.py keymapper/parse/Makefile 1.0 05/01/22 18:51:05 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/parse/Makefile keymapper/keymap.py 1.6 05/01/22 18:51:05 smurf@smurf.noris.de +119 -16 detect if a keymap is a subset of another add objects for modifier keys keymapper/graph.py 1.5 05/01/22 18:51:05 smurf@smurf.noris.de +18 -5 print unicode names, not characters gen_map.py 1.7 05/01/22 18:51:05 smurf@smurf.noris.de +24 -7 added a bunch of options: - min keymap length - verbosity debian/control 1.3 05/01/22 18:51:05 smurf@smurf.noris.de +2 -1 depend on bugfixed yapps2 runtime data/symbols 1.0 05/01/22 18:51:05 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/data/symbols Makefile 1.0 05/01/22 18:51:05 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/Makefile data/keymaps 1.2 05/01/22 18:51:04 smurf@smurf.noris.de +87 -84 mangled keymapper/parse/maps.py 1.6 05/01/21 06:11:15 smurf@smurf.noris.de +0 -0 Rename: keymapper/maps.py -> keymapper/parse/maps.py ChangeSet 1.11 05/01/20 13:59:28 smurf@smurf.noris.de +3 -0 Bugfix: the last entry of each line was skipped. added option to dump the map data keymapper/maps.py 1.5 05/01/20 13:59:28 smurf@smurf.noris.de +3 -3 don't skip the last part of each line ..! keymapper/keymap.py 1.5 05/01/20 13:59:28 smurf@smurf.noris.de +18 -4 add separate symbol->code list for happier dumping gen_map.py 1.6 05/01/20 13:59:28 smurf@smurf.noris.de +22 -8 add option to dump the keymap data ChangeSet 1.10 05/01/20 13:56:46 smurf@smurf.noris.de +2 -0 document graph output suggest graphviz debian/control 1.2 05/01/20 13:56:46 smurf@smurf.noris.de +1 -0 sugest graphviz README 1.4 05/01/20 13:56:46 smurf@smurf.noris.de +7 -0 doc graph output data/keymaps 1.1 05/01/20 13:18:07 smurf@smurf.noris.de +98 -0 ChangeSet 1.9 05/01/20 13:18:07 smurf@smurf.noris.de +8 -0 Checked in the keyboard map importer (missing from last checkin) test_gen_map.py 1.4 05/01/20 13:18:07 smurf@smurf.noris.de +7 -3 Add creating a graphviz map keymapper/tree.py 1.4 05/01/20 13:18:07 smurf@smurf.noris.de +28 -21 added wrapper for report generation keymapper/maps.py 1.4 05/01/20 13:18:07 smurf@smurf.noris.de +51 -44 Import keyboard maps Added better error handling for broken map files. Added graphviz output (.dot files) for better visualization. keymapper/keymap.py 1.4 05/01/20 13:18:07 smurf@smurf.noris.de +1 -6 kill SymbolKnown exception keymapper/graph.py 1.4 05/01/20 13:18:07 smurf@smurf.noris.de +23 -10 Generate a .dot file for graphviz (copy of file.py) gen_map.py 1.5 05/01/20 13:18:07 smurf@smurf.noris.de +54 -32 Add creating a graphviz .dot map file Encode normal output as utf-8, graphviz output as latin-1 (for now) Add error handling for not-found/broken/misencoded map files data/keymaps 1.0 05/01/20 13:18:07 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/data/keymaps BitKeeper/etc/ignore 1.5 05/01/20 13:18:07 smurf@smurf.noris.de +1 -0 Added test.dot to the ignore list keymapper/graph.py 1.3 05/01/20 12:09:32 smurf@smurf.noris.de +0 -0 bk cp keymapper/file.py keymapper/graph.py ChangeSet 1.8 05/01/20 11:21:26 smurf@smurf.noris.de +4 -0 Sometimes, symbols may appear on more than one key. Extended the algorithm to deal with that. Found a crucial algorithm bug. Added a it of tracing while we're at it. keymapper/tree.py 1.3 05/01/20 11:21:26 smurf@smurf.noris.de +58 -28 Allow symbols to appear on more than one key. Fix a small but crucial algorithm bug: the chooser was not correctly restarted, which broke backtracking. Add algortihm tracing. keymapper/keymap.py 1.3 05/01/20 11:21:26 smurf@smurf.noris.de +12 -3 Allow symbols to show up on more than one key. Add "dump" method to a keymap for terse reporting. keymapper/fakequery.py 1.3 05/01/20 11:21:26 smurf@smurf.noris.de +2 -1 Random selection: If a symbol appears on more than one key, select one. keymapper/fakemaps.py 1.3 05/01/20 11:21:26 smurf@smurf.noris.de +4 -0 Additional test map: a symbol appears on two keys. keymapper/maps.py 1.3 05/01/20 03:59:01 smurf@smurf.noris.de +0 -0 bk cp keymapper/fakemaps.py keymapper/maps.py test_gen_map.py 1.3 05/01/20 03:36:54 smurf@smurf.noris.de +0 -0 Rename: test_mapper.py -> test_gen_map.py gen_map.py 1.4 05/01/20 03:36:42 smurf@smurf.noris.de +0 -0 Rename: mapper.py -> gen_map.py mapper.py 1.3 05/01/20 03:36:18 smurf@smurf.noris.de +0 -0 bk cp test_mapper.py mapper.py ChangeSet 1.7 04/12/23 18:55:00 smurf@smurf.noris.de +8 -0 added debian/ subtree debian/rules 1.1 04/12/23 18:54:59 smurf@smurf.noris.de +79 -0 debian/docs 1.1 04/12/23 18:54:59 smurf@smurf.noris.de +1 -0 debian/dirs 1.1 04/12/23 18:54:59 smurf@smurf.noris.de +1 -0 debian/copyright 1.1 04/12/23 18:54:59 smurf@smurf.noris.de +12 -0 debian/control 1.1 04/12/23 18:54:59 smurf@smurf.noris.de +15 -0 debian/compat 1.1 04/12/23 18:54:59 smurf@smurf.noris.de +1 -0 debian/changelog 1.1 04/12/23 18:54:59 smurf@smurf.noris.de +7 -0 debian/rules 1.0 04/12/23 18:54:59 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/debian/rules debian/docs 1.0 04/12/23 18:54:59 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/debian/docs debian/dirs 1.0 04/12/23 18:54:59 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/debian/dirs debian/copyright 1.0 04/12/23 18:54:59 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/debian/copyright debian/control 1.0 04/12/23 18:54:59 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/debian/control debian/compat 1.0 04/12/23 18:54:59 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/debian/compat debian/changelog 1.0 04/12/23 18:54:59 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/debian/changelog BitKeeper/etc/ignore 1.4 04/12/23 18:39:36 smurf@smurf.noris.de +3 -0 added *-stamp debian/files debian/tmp/* ChangeSet 1.6 04/12/23 17:48:24 smurf@smurf.noris.de +9 -0 Added a bunch of comments tree.py had a few problems with its selection code test_mapper.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +24 -3 Added a bunch of comments mapper.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +24 -3 Added a bunch of comments keymapper/tree.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +126 -77 Added a bunch of comments fixed up the selection code a bit keymapper/script.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +13 -2 Added a bunch of comments keymapper/query.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +13 -0 Added a bunch of comments keymapper/maps.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +15 -2 Added a bunch of comments keymapper/keymap.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +15 -10 Added a bunch of comments keymapper/graph.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +4 -0 Added a bunch of comments keymapper/file.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +4 -0 Added a bunch of comments keymapper/fakequery.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +6 -2 Added a bunch of comments keymapper/fakemaps.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +15 -2 Added a bunch of comments keymapper/__init__.py 1.2 04/12/23 17:48:23 smurf@smurf.noris.de +4 -0 Added a bunch of comments test_mapper.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +36 -0 mapper.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +36 -0 keymapper/tree.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +493 -0 keymapper/script.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +98 -0 keymapper/query.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +34 -0 keymapper/maps.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +52 -0 keymapper/keymap.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +60 -0 keymapper/graph.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +43 -0 keymapper/file.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +43 -0 keymapper/fakequery.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +35 -0 keymapper/fakemaps.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +52 -0 keymapper/__init__.py 1.1 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 ChangeSet 1.5 04/12/23 15:54:29 smurf@smurf.noris.de +11 -0 Added a whole lot of code. test_mapper.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/test_mapper.py mapper.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/test_mapper.py keymapper/tree.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/tree.py keymapper/script.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/script.py keymapper/query.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/query.py keymapper/maps.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/fakemaps.py keymapper/keymap.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/keymap.py keymapper/graph.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/file.py keymapper/file.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/file.py keymapper/fakequery.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/fakequery.py keymapper/fakemaps.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/fakemaps.py keymapper/__init__.py 1.0 04/12/23 15:54:29 smurf@smurf.noris.de +0 -0 BitKeeper file /daten/src/debian/keymapper/keymapper/__init__.py README 1.3 04/12/23 15:54:29 smurf@smurf.noris.de +35 -7 added stuff BitKeeper/etc/ignore 1.3 04/12/23 15:54:09 smurf@smurf.noris.de +2 -0 added *.swp *.swo BitKeeper/etc/ignore 1.2 04/12/23 15:53:48 smurf@smurf.noris.de +2 -0 added *.pyc *.pyo ChangeSet 1.4 04/12/17 09:53:31 smurf@smurf.noris.de +1 -0 glyph lookalikes ? README 1.2 04/12/17 09:53:30 smurf@smurf.noris.de +2 -1 glyph lookalikes ? ChangeSet 1.3 04/12/17 09:51:54 smurf@smurf.noris.de +1 -0 initial design notes README 1.1 04/12/17 09:51:53 smurf@smurf.noris.de +75 -0 README 1.0 04/12/17 09:51:53 smurf@smurf.noris.de +0 -0 BitKeeper file /usr/local/src/debian/keymapper/README ChangeSet 1.2 04/12/17 05:17:39 smurf@smurf.noris.de +1 -0 version number / changelog auto-update BitKeeper/etc/logging_ok 1.1 04/12/17 05:17:39 smurf@smurf.noris.de +1 -0 ChangeSet 1.1 04/12/17 05:17:39 smurf@smurf.noris.de +3 -0 Initial repository create BitKeeper/etc/logging_ok 1.0 04/12/17 05:17:39 smurf@smurf.noris.de +0 -0 BitKeeper file /tmp/b.s.12379/BitKeeper/etc/logging_ok BitKeeper/etc/ignore 1.1 04/12/17 05:17:36 smurf@smurf.noris.de +2 -0 BitKeeper/etc/config 1.1 04/12/17 05:17:36 smurf@smurf.noris.de +13 -0 ChangeSet 1.0 04/12/17 05:17:36 smurf@smurf.noris.de +0 -0 BitKeeper file /tmp/b.s.12379/ChangeSet BitKeeper/etc/ignore 1.0 04/12/17 05:17:36 smurf@smurf.noris.de +0 -0 BitKeeper file /tmp/b.s.12379/BitKeeper/etc/ignore BitKeeper/etc/config 1.0 04/12/17 05:17:36 smurf@smurf.noris.de +0 -0 BitKeeper file /tmp/b.s.12379/BitKeeper/etc/config