163 lines
4.4 KiB
Python
163 lines
4.4 KiB
Python
#!/usr/bin/env python
|
|
|
|
# Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
|
# Copyright (C) 2011 Red Hat, Inc.
|
|
|
|
# This library is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public License
|
|
# as published by the Free Software Foundation; either version 2 of
|
|
# the License, or (at your option) any later version.
|
|
|
|
# This library 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
|
|
# Lesser General Public License for more details.
|
|
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this library; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
# 02110-1301 USA
|
|
|
|
import sys, os.path
|
|
import sys
|
|
import re
|
|
|
|
import gtk, gtk.gdk
|
|
import eekboard
|
|
from gi.repository import Eek, GLib
|
|
|
|
if len(sys.argv) < 3:
|
|
print >> sys.stderr, "Usage: %s KEYBOARD M17N-MAP..." % sys.argv[0]
|
|
sys.exit(-1)
|
|
|
|
MAPENTRY_PATTERN = re.compile(r'\A\s*\((?:\((.*?)\)|"(.*?)")\s*"(.*?)"\)')
|
|
KEYCODE_TABLE = {
|
|
'1': 10,
|
|
'2': 11,
|
|
'3': 12,
|
|
'4': 13,
|
|
'5': 14,
|
|
'6': 15,
|
|
'7': 16,
|
|
'8': 17,
|
|
'9': 18,
|
|
'0': 19,
|
|
'-': 20,
|
|
'=': 21,
|
|
'q': 24,
|
|
'w': 25,
|
|
'e': 26,
|
|
'r': 27,
|
|
't': 28,
|
|
'y': 29,
|
|
'u': 30,
|
|
'i': 31,
|
|
'o': 32,
|
|
'p': 33,
|
|
'[': 34,
|
|
']': 35,
|
|
'a': 38,
|
|
's': 39,
|
|
'd': 40,
|
|
'f': 41,
|
|
'g': 42,
|
|
'h': 43,
|
|
'j': 44,
|
|
'k': 45,
|
|
'l': 46,
|
|
';': 47,
|
|
'\'': 48,
|
|
'`': 49,
|
|
'\\': 51,
|
|
'z': 52,
|
|
'x': 53,
|
|
'c': 54,
|
|
'v': 55,
|
|
'b': 56,
|
|
'n': 57,
|
|
'm': 58,
|
|
',': 59,
|
|
'.': 60,
|
|
'/': 61
|
|
}
|
|
|
|
MARK_UPPER = '~!@#$%^&*()_+{}|:"<>?'
|
|
MARK_LOWER = '`1234567890-=[]\\;\',./'
|
|
|
|
class MapFile(object):
|
|
def __init__(self, path):
|
|
self.__dict = dict()
|
|
|
|
with open(path, 'r') as fp:
|
|
for line in fp:
|
|
match = re.match(MAPENTRY_PATTERN, line)
|
|
if match:
|
|
insert = match.group(3).decode('UTF-8')
|
|
if match.group(1):
|
|
keyseq = re.sub(r'\\(.)', r'\1', match.group(1))
|
|
self.__add_symbol_entry(keyseq, insert)
|
|
else:
|
|
keyseq = re.sub(r'\\(.)', r'\1', match.group(2))
|
|
self.__add_text_entry(keyseq, insert)
|
|
|
|
def get_entry_for_keycode(self, keycode):
|
|
return self.__dict.get(keycode, list([None, None, None, None]))
|
|
|
|
def __add_entry(self, letter, level, insert):
|
|
if letter.isupper():
|
|
level |= 1
|
|
letter = letter.lower()
|
|
elif letter in MARK_UPPER:
|
|
level |= 1
|
|
letter = MARK_LOWER[MARK_UPPER.index(letter)]
|
|
keycode = KEYCODE_TABLE[letter]
|
|
if keycode not in self.__dict:
|
|
self.__dict[keycode] = list([None,None,None,None])
|
|
self.__dict[keycode][level] = insert
|
|
|
|
def __add_symbol_entry(self, symbol, insert):
|
|
level = 0
|
|
if symbol.startswith('G-'):
|
|
level |= 2
|
|
symbol = symbol[2:]
|
|
if not symbol.startswith('KP_'):
|
|
self.__add_entry(symbol, level, insert)
|
|
|
|
def __add_text_entry(self, text, insert):
|
|
self.__add_entry(text, 0, insert)
|
|
|
|
files = list()
|
|
for path in sys.argv[2:]:
|
|
files.append(MapFile(path))
|
|
|
|
keyboard = eekboard.XmlKeyboard(os.path.abspath(sys.argv[1]))
|
|
|
|
def each_key(element, data):
|
|
keycode = element.get_keycode()
|
|
matrix = Eek.SymbolMatrix.new(len(files) + 1, 4)
|
|
for l in xrange(4):
|
|
keysym = element.get_symbol_at_index(0, l, 0, 0)
|
|
matrix.set_symbol(0, l, keysym)
|
|
for g, f in enumerate(files):
|
|
entry = f.get_entry_for_keycode(keycode)
|
|
for l in xrange(4):
|
|
keysym = None
|
|
if entry[l]:
|
|
try:
|
|
keyval = gtk.gdk.unicode_to_keyval(ord(entry[l]))
|
|
keysym = Eek.Keysym.new(keyval)
|
|
except:
|
|
pass
|
|
if not keysym:
|
|
keysym = element.get_symbol_at_index(g + 1, l, 0, 0)
|
|
matrix.set_symbol(g + 1, l, keysym)
|
|
element.set_symbol_matrix(matrix)
|
|
|
|
def each_section(element, data):
|
|
element.foreach_child(each_key, None)
|
|
|
|
keyboard.foreach_child(each_section, None)
|
|
output = GLib.string_sized_new(4096)
|
|
keyboard.output(output, 0)
|
|
print output.str
|