Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWade Brainerd <wadetb@gmail.com>2009-11-19 00:58:04 (GMT)
committer Wade Brainerd <wadetb@gmail.com>2009-11-19 00:58:04 (GMT)
commit49ca80749aa0a5a23595cdb67105ca700e4bd2f4 (patch)
treeeac87616c1e3b6e725c356b19e0f4f32e998a2df
parent0333a2bb7b1711641739a155c6131e6c4113a7e6 (diff)
Use GDK as a fallback when a custom keymap is not present. Also display a reasonable error when a key is not understood.
-rw-r--r--keyboard.py41
-rw-r--r--lessons/en_US.key100
-rw-r--r--lessonscreen.py9
3 files changed, 39 insertions, 111 deletions
diff --git a/keyboard.py b/keyboard.py
index 4887183..45389f7 100644
--- a/keyboard.py
+++ b/keyboard.py
@@ -238,7 +238,7 @@ class KeyboardData:
self.keys = None
self.key_scan_map = None
- self.letter_map = {}
+ self.letter_map = {}
# Access the current GTK keymap.
self.keymap = gtk.gdk.keymap_get_default()
@@ -365,13 +365,11 @@ class KeyboardData:
return None
def get_key_state_group_for_letter(self, letter):
- """Returns a (key, modifier_state) which when pressed will generate letter."""
- # Special processing for the enter key.
+ # Special processing for some keys.
if letter == '\n' or letter == PARAGRAPH_CODE:
return self.find_key_by_label('enter'), 0, 0
- # Look up the key in the letter map.
- # Find the one with the fewest modifier keys.
+ # Try the letter map, if loaded.
best_score = 3
best_result = None
@@ -379,6 +377,7 @@ class KeyboardData:
if unicode(l) == unicode(letter):
scan, state, group = self.parse_key_sig(sig)
+ # Choose the key with the fewest modifiers.
score = 0
if state & gtk.gdk.SHIFT_MASK: score += 1
if state & gtk.gdk.MOD5_MASK: score += 1
@@ -391,8 +390,35 @@ class KeyboardData:
if k['key-scan'] == best_result[0]:
return k, best_result[1], best_result[2]
+ # Try the GDK keymap.
+ keyval = gtk.gdk.unicode_to_keyval(ord(letter))
+ entries = self.keymap.get_entries_for_keyval(keyval)
+ for e in entries:
+ for k in self.keys:
+ if k['key-scan'] == e[0]:
+ # TODO: Level -> state calculations are hardcoded to what the XO keyboard does.
+ # They were discovered through experimentation.
+ state = 0
+ if e[2] & 1:
+ state |= gtk.gdk.SHIFT_MASK
+ if e[2] & 2:
+ state |= gtk.gdk.MOD5_MASK
+ return k, state, e[1]
+
+ # Fail!
return None, None, None
+ def get_letter_for_key_state_group(self, key, state, group):
+ sig = self.format_key_sig(key['key-scan'], state, group)
+ if self.letter_map.has_key(sig):
+ return self.letter_map[sig]
+ else:
+ t = self.keymap.translate_keyboard_state(key['key-scan'], self.active_state, self.active_group)
+ if t:
+ return unichr(gtk.gdk.keyval_to_unicode(t[0]))
+
+ return ''
+
class KeyboardWidget(KeyboardData, gtk.DrawingArea):
"""A GTK widget which implements an interactive visual keyboard, with support
for custom data driven layouts."""
@@ -494,11 +520,8 @@ class KeyboardWidget(KeyboardData, gtk.DrawingArea):
text = ''
if k['key-label']:
text = k['key-label']
-
else:
- sig = self.format_key_sig(k['key-scan'], self.active_state, self.active_group)
- if self.letter_map.has_key(sig):
- text = self.letter_map[sig]
+ text = self.get_letter_for_key_state_group(k, self.active_state, self.active_group)
try:
layout = self.create_pango_layout(unicode(text))
diff --git a/lessons/en_US.key b/lessons/en_US.key
deleted file mode 100644
index 06b9d7f..0000000
--- a/lessons/en_US.key
+++ /dev/null
@@ -1,100 +0,0 @@
-{
- "scan10": "1",
- "scan10 shift": "!",
- "scan11": "2",
- "scan11 shift": "@",
- "scan12": "3",
- "scan12 shift": "#",
- "scan13": "4",
- "scan13 shift": "$",
- "scan14": "5",
- "scan14 shift": "%",
- "scan15": "6",
- "scan15 shift": "^",
- "scan16": "7",
- "scan16 shift": "&",
- "scan17": "8",
- "scan17 shift": "*",
- "scan18": "9",
- "scan18 shift": "(",
- "scan19": "0",
- "scan19 shift": ")",
- "scan20": "-",
- "scan20 shift": "_",
- "scan21": "=",
- "scan21 shift": "+",
- "scan24": "q",
- "scan24 shift": "Q",
- "scan25": "w",
- "scan25 shift": "W",
- "scan26": "e",
- "scan26 shift": "E",
- "scan27": "r",
- "scan27 shift": "R",
- "scan28": "t",
- "scan28 shift": "T",
- "scan29": "y",
- "scan29 shift": "Y",
- "scan30": "u",
- "scan30 shift": "U",
- "scan31": "i",
- "scan31 shift": "I",
- "scan32": "o",
- "scan32 shift": "O",
- "scan33": "p",
- "scan33 shift": "P",
- "scan34": "[",
- "scan34 shift": "{",
- "scan35": "]",
- "scan35 shift": "}",
- "scan36": "\r",
- "scan36 shift": "\r",
- "scan38": "a",
- "scan38 shift": "A",
- "scan39": "s",
- "scan39 shift": "S",
- "scan40": "d",
- "scan40 shift": "D",
- "scan41": "f",
- "scan41 shift": "F",
- "scan42": "g",
- "scan42 shift": "G",
- "scan43": "h",
- "scan43 shift": "H",
- "scan44": "j",
- "scan44 shift": "J",
- "scan45": "k",
- "scan45 shift": "K",
- "scan46": "l",
- "scan46 shift": "L",
- "scan47": ";",
- "scan47 shift": ":",
- "scan48": "'",
- "scan48 shift": "\"",
- "scan49": "`",
- "scan49 shift": "~",
- "scan51": "\\",
- "scan51 shift": "|",
- "scan52": "z",
- "scan52 shift": "Z",
- "scan53": "x",
- "scan53 shift": "X",
- "scan54": "c",
- "scan54 shift": "C",
- "scan55": "v",
- "scan55 shift": "V",
- "scan56": "b",
- "scan56 shift": "B",
- "scan57": "n",
- "scan57 shift": "N",
- "scan58": "m",
- "scan58 shift": "M",
- "scan59": ",",
- "scan59 shift": "<",
- "scan60": ".",
- "scan60 shift": ">",
- "scan61": "/",
- "scan61 shift": "?",
- "scan65": " ",
- "scan65 shift": " "
-} \ No newline at end of file
diff --git a/lessonscreen.py b/lessonscreen.py
index 58a3946..e7d66e7 100644
--- a/lessonscreen.py
+++ b/lessonscreen.py
@@ -135,7 +135,7 @@ class LessonScreen(gtk.VBox):
try:
self.keyboard.load_letter_map('lessons/%s.key' % code)
except:
- self.keyboard.load_letter_map('lessons/en_US.key')
+ pass
self.keyboard.set_layout(keyboard.OLPC_LAYOUT)
@@ -536,7 +536,12 @@ class LessonScreen(gtk.VBox):
pixbuf = self.keyboard.get_key_pixbuf(key, state, group, 1)
self.lessonbuffer.insert_pixbuf(self.lessonbuffer.get_end_iter(), pixbuf)
-
+
+ else: # No key found in the keymap.
+ instructions = _("Uh oh! Your keyboard cannot type the letter '%s'.\n") % char
+ instructions += _("Please change your keyboard settings and try this lesson again.")
+ self.lessonbuffer.insert(self.lessonbuffer.get_end_iter(), instructions + '\n\n')
+
self.lessonbuffer.apply_tag_by_name('image',
self.lessonbuffer.get_iter_at_mark(self.line_marks[0]),
self.lessonbuffer.get_end_iter())