From 49ca80749aa0a5a23595cdb67105ca700e4bd2f4 Mon Sep 17 00:00:00 2001 From: Wade Brainerd Date: Thu, 19 Nov 2009 00:58:04 +0000 Subject: Use GDK as a fallback when a custom keymap is not present. Also display a reasonable error when a key is not understood. --- 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()) -- cgit v0.9.1