key-mon-1.17/0000750006766500116100000000000012261424504014532 5ustar scottkirkwoodeng00000000000000key-mon-1.17/src/0000750006766500116100000000000012261424504015321 5ustar scottkirkwoodeng00000000000000key-mon-1.17/src/key-mon0000750006766500116100000000007012130344127016620 0ustar scottkirkwoodeng00000000000000#!/usr/bin/python import keymon.key_mon as km km.main() key-mon-1.17/src/keymon/0000750006766500116100000000000012261424504016623 5ustar scottkirkwoodeng00000000000000key-mon-1.17/src/keymon/key_mon.py0000750006766500116100000011345712261421461020653 0ustar scottkirkwoodeng00000000000000#!/usr/bin/python # # Copyright 2010 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Keyboard Status Monitor. Monitors one or more keyboards and mouses. Shows their status graphically. """ __author__ = 'Scott Kirkwood (scott+keymon@forusers.com)' __version__ = '1.17' import locale import logging import pygtk pygtk.require('2.0') import gettext import gobject import gtk import os import sys import time try: import xlib except ImportError: print 'Error: Missing xlib, run sudo apt-get install python-xlib' sys.exit(-1) import options import lazy_pixbuf_creator import mod_mapper import settings import shaped_window import two_state_image from ConfigParser import SafeConfigParser gettext.install('key-mon', 'locale') def fix_svg_key_closure(fname, from_tos): """Create a closure to modify the key. Args: from_tos: list of from, to pairs for search replace. Returns: A bound function which returns the file fname with modifications. """ def fix_svg_key(): """Given an SVG file return the SVG text fixed.""" logging.debug('Read file %r', fname) fin = open(fname) fbytes = fin.read() fin.close() for fin, t in from_tos: # Quick XML escape fix t = t.replace('<', '<') fbytes = fbytes.replace(fin, t) return fbytes return fix_svg_key def cstrf(func): """Change locale before using str function""" OLD_CTYPE = locale.getlocale(locale.LC_CTYPE) locale.setlocale(locale.LC_CTYPE, 'C') s = func() locale.setlocale(locale.LC_CTYPE, OLD_CTYPE) return s class KeyMon: """main KeyMon window class.""" def __init__(self, options): """Create the Key Mon window. Options dict: scale: float 1.0 is default which means normal size. meta: boolean show the meta (windows key) kbd_file: string Use the kbd file given. emulate_middle: Emulate the middle mouse button. theme: Name of the theme to use to draw keys """ settings.SettingsDialog.register() self.btns = ['MOUSE', 'BTN_RIGHT', 'BTN_MIDDLE', 'BTN_MIDDLERIGHT', 'BTN_LEFT', 'BTN_LEFTRIGHT', 'BTN_LEFTMIDDLE', 'BTN_LEFTMIDDLERIGHT'] self.options = options self.pathname = os.path.dirname(os.path.abspath(__file__)) if self.options.scale < 1.0: self.svg_size = '-small' else: self.svg_size = '' # Make lint happy by defining these. self.hbox = None self.window = None self.event_box = None self.mouse_indicator_win = None self.key_image = None self.buttons = None self.no_press_timer = None self.move_dragged = False self.shape_mask_current = None self.shape_mask_cache = {} self.MODS = ['SHIFT', 'CTRL', 'META', 'ALT'] self.IMAGES = ['MOUSE'] + self.MODS self.images = dict([(img, None) for img in self.IMAGES]) self.enabled = dict([(img, self.get_option(cstrf(img.lower))) for img in self.IMAGES]) self.options.kbd_files = settings.get_kbd_files() self.modmap = mod_mapper.safely_read_mod_map(self.options.kbd_file, self.options.kbd_files) self.name_fnames = self.create_names_to_fnames() self.devices = xlib.XEvents() self.devices.start() self.pixbufs = lazy_pixbuf_creator.LazyPixbufCreator(self.name_fnames, self.options.scale) self.create_window() self.reset_no_press_timer() def get_option(self, attr): """Shorthand for getattr(self.options, attr)""" return getattr(self.options, attr) def do_screenshot(self): """Create a screenshot showing some keys.""" for key in self.options.screenshot.split(','): try: if key == 'KEY_EMPTY': continue if key.startswith('KEY_'): key_info = self.modmap.get_from_name(key) if not key_info: print 'Key %s not found' % key self.destroy(None) return scancode = key_info[0] event = xlib.XEvent('EV_KEY', scancode=scancode, code=key, value=1) elif key.startswith('BTN_'): event = xlib.XEvent('EV_KEY', scancode=0, code=key, value=1) self.handle_event(event) while gtk.events_pending(): gtk.main_iteration(False) time.sleep(0.1) except Exception, exp: print exp while gtk.events_pending(): gtk.main_iteration(False) time.sleep(0.1) win = self.window x, y = win.get_position() w, h = win.get_size() screenshot = gtk.gdk.Pixbuf.get_from_drawable( gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h), gtk.gdk.get_default_root_window(), gtk.gdk.colormap_get_system(), x, y, 0, 0, w, h) fname = 'screenshot.png' screenshot.save(fname, 'png') print 'Saved screenshot %r' % fname self.destroy(None) def create_names_to_fnames(self): """Give a name to images.""" if self.options.scale < 1.0: self.svg_size = '-small' else: self.svg_size = '' ftn = { 'MOUSE': [self.svg_name('mouse'),], 'BTN_MIDDLE': [self.svg_name('mouse'), self.svg_name('middle-mouse')], 'SCROLL_UP': [self.svg_name('mouse'), self.svg_name('scroll-up-mouse')], 'SCROLL_DOWN': [self.svg_name('mouse'), self.svg_name('scroll-dn-mouse')], 'REL_LEFT': [self.svg_name('mouse'), self.svg_name('sroll-lft-mouse')], 'REL_RIGHT': [self.svg_name('mouse'), self.svg_name('scroll-rgt-mouse')], 'SHIFT': [self.svg_name('shift')], 'SHIFT_EMPTY': [self.svg_name('shift'), self.svg_name('whiteout-72')], 'CTRL': [self.svg_name('ctrl')], 'CTRL_EMPTY': [self.svg_name('ctrl'), self.svg_name('whiteout-58')], 'META': [self.svg_name('meta'), self.svg_name('meta')], 'META_EMPTY': [self.svg_name('meta'), self.svg_name('whiteout-58')], 'ALT': [self.svg_name('alt')], 'ALT_EMPTY': [self.svg_name('alt'), self.svg_name('whiteout-58')], 'ALTGR': [self.svg_name('altgr')], 'ALTGR_EMPTY': [self.svg_name('altgr'), self.svg_name('whiteout-58')], 'KEY_EMPTY': [ fix_svg_key_closure(self.svg_name('one-char-template'), [('&', '')]), self.svg_name('whiteout-48')], 'BTN_LEFTRIGHT': [ self.svg_name('mouse'), self.svg_name('left-mouse'), self.svg_name('right-mouse')], 'BTN_LEFTMIDDLERIGHT': [ self.svg_name('mouse'), self.svg_name('left-mouse'), self.svg_name('middle-mouse'), self.svg_name('right-mouse')], } if self.options.swap_buttons: # swap the meaning of left and right left_str = 'right' right_str = 'left' else: left_str = 'left' right_str = 'right' ftn.update({ 'BTN_RIGHT': [self.svg_name('mouse'), self.svg_name('%s-mouse' % right_str)], 'BTN_LEFT': [self.svg_name('mouse'), self.svg_name('%s-mouse' % left_str)], 'BTN_LEFTMIDDLE': [ self.svg_name('mouse'), self.svg_name('%s-mouse' % left_str), self.svg_name('middle-mouse')], 'BTN_MIDDLERIGHT': [ self.svg_name('mouse'), self.svg_name('middle-mouse'), self.svg_name('%s-mouse' % right_str)], }) if self.options.scale >= 1.0: ftn.update({ 'KEY_SPACE': [ fix_svg_key_closure(self.svg_name('two-line-wide'), [('TOP', 'Space'), ('BOTTOM', '')])], 'KEY_TAB': [ fix_svg_key_closure(self.svg_name('two-line-wide'), [('TOP', 'Tab'), ('BOTTOM', u'\u21B9')])], 'KEY_BACKSPACE': [ fix_svg_key_closure(self.svg_name('two-line-wide'), [('TOP', 'Back'), ('BOTTOM', u'\u21fd')])], 'KEY_RETURN': [ fix_svg_key_closure(self.svg_name('two-line-wide'), [('TOP', 'Enter'), ('BOTTOM', u'\u23CE')])], 'KEY_CAPS_LOCK': [ fix_svg_key_closure(self.svg_name('two-line-wide'), [('TOP', 'Capslock'), ('BOTTOM', '')])], 'KEY_MULTI_KEY': [ fix_svg_key_closure(self.svg_name('two-line-wide'), [('TOP', 'Compose'), ('BOTTOM', '')])], }) else: ftn.update({ 'KEY_SPACE': [ fix_svg_key_closure(self.svg_name('one-line-wide'), [('&', 'Space')])], 'KEY_TAB': [ fix_svg_key_closure(self.svg_name('one-line-wide'), [('&', 'Tab')])], 'KEY_BACKSPACE': [ fix_svg_key_closure(self.svg_name('one-line-wide'), [('&', 'Back')])], 'KEY_RETURN': [ fix_svg_key_closure(self.svg_name('one-line-wide'), [('&', 'Enter')])], 'KEY_CAPS_LOCK': [ fix_svg_key_closure(self.svg_name('one-line-wide'), [('&', 'Capslck')])], 'KEY_MULTI_KEY': [ fix_svg_key_closure(self.svg_name('one-line-wide'), [('&', 'Compose')])], }) return ftn def create_window(self): """Create the main window.""" self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_resizable(False) self.window.set_title('Keyboard Status Monitor') width, height = 30 * self.options.scale, 48 * self.options.scale self.window.set_default_size(int(width), int(height)) self.window.set_decorated(self.options.decorated) self.mouse_indicator_win = shaped_window.ShapedWindow( self.svg_name('mouse-indicator'), timeout=self.options.visible_click_timeout) self.mouse_follower_win = shaped_window.ShapedWindow( self.svg_name('mouse-follower')) if self.options.follow_mouse: self.mouse_follower_win.show() self.window.set_opacity(self.options.opacity) self.window.set_keep_above(True) self.event_box = gtk.EventBox() self.window.add(self.event_box) self.event_box.show() self.create_images() self.hbox = gtk.HBox(False, 0) self.event_box.add(self.hbox) self.layout_boxes() self.hbox.show() self.add_events() self.set_accept_focus(False) self.window.set_skip_taskbar_hint(True) old_x = self.options.x_pos old_y = self.options.y_pos if old_x != -1 and old_y != -1 and old_x and old_y: self.window.move(old_x, old_y) self.window.show() def update_shape_mask(self, *unused_args, **kwargs): if not self.options.backgroundless: return force = kwargs.get('force', False) btns = [btn for btn in self.buttons if btn.get_visible()] # Generate id to see if current mask needs to be updated, which is a tuple # of allocation of buttons. cache_id = tuple(tuple(btn.get_allocation()) for btn in btns) if cache_id == self.shape_mask_current and not force: return # Try to find existing mask in cache # TODO limit number of cached masks shape_mask = self.shape_mask_cache.get(cache_id, None) if shape_mask and not force: self.window.shape_combine_mask(shape_mask, 0, 0) self.shape_mask_current = cache_id return _, _, width, height = self.window.get_allocation() masks = [self.pixbufs.get(btn.current).render_pixmap_and_mask()[1] \ for btn in btns] shape_mask = gtk.gdk.Pixmap(None, width, height, masks[0].get_depth()) gc = gtk.gdk.GC(shape_mask) # Initialize the mask just in case masks of buttons can't fill the window, # if that happens, some artifacts will be seen usually at right edge. gc.set_foreground( gtk.gdk.Color(pixel=0) if self.options.backgroundless else \ gtk.gdk.Color(pixel=1)) shape_mask.draw_rectangle(gc, True, 0, 0, width, height) for btn_allocation, mask in zip(cache_id, masks): # Don't create mask until every image is allocated if btn_allocation[0] == -1: return shape_mask.draw_drawable(gc, mask, 0, 0, *btn_allocation) self.window.shape_combine_mask(shape_mask, 0, 0) self.shape_mask_current = cache_id self.shape_mask_cache[cache_id] = shape_mask def create_images(self): self.images['MOUSE'] = two_state_image.TwoStateImage(self.pixbufs, 'MOUSE') for img in self.MODS: self.images[img] = two_state_image.TwoStateImage( self.pixbufs, img + '_EMPTY', self.enabled[img]) self.create_buttons() def create_buttons(self): self.buttons = list(self.images[img] for img in self.IMAGES) for _ in range(self.options.old_keys): key_image = two_state_image.TwoStateImage(self.pixbufs, 'KEY_EMPTY') self.buttons.append(key_image) self.key_image = two_state_image.TwoStateImage(self.pixbufs, 'KEY_EMPTY') self.buttons.append(self.key_image) for but in self.buttons: if but.normal == 'MOUSE': but.timeout_secs = self.options.mouse_timeout else: but.timeout_secs = self.options.key_timeout but.connect('size_allocate', self.update_shape_mask) def layout_boxes(self): for child in self.hbox.get_children(): self.hbox.remove(child) for img in self.IMAGES: if not self.enabled[img]: self.images[img].hide() self.hbox.pack_start(self.images[img], False, False, 0) prev_key_image = None for key_image in self.buttons[-(self.options.old_keys + 1):-1]: # key_image.hide() #key_image.timeout_secs = 0.5 key_image.defer_to = prev_key_image self.hbox.pack_start(key_image, True, True, 0) prev_key_image = key_image # This must be after the loop above. #self.key_image.timeout_secs = 0.5 self.key_image.defer_to = prev_key_image self.hbox.pack_start(self.key_image, True, True, 0) def svg_name(self, fname): """Return an svg filename given the theme, system.""" themepath = self.options.themes[self.options.theme][1] fullname = os.path.join(themepath, '%s%s.svg' % (fname, self.svg_size)) if self.svg_size and not os.path.exists(fullname): # Small not found, defaulting to large size fullname = os.path.join(themepath, '%s.svg' % fname) return fullname def add_events(self): """Add events for the window to listen to.""" self.window.connect('destroy', self.destroy) self.window.connect('button-press-event', self.button_pressed) self.window.connect('button-release-event', self.button_released) self.window.connect('leave-notify-event', self.pointer_leave) self.event_box.connect('button_release_event', self.right_click_handler) accelgroup = gtk.AccelGroup() key, modifier = gtk.accelerator_parse('q') accelgroup.connect_group(key, modifier, gtk.ACCEL_VISIBLE, self.quit_program) key, modifier = gtk.accelerator_parse('s') accelgroup.connect_group(key, modifier, gtk.ACCEL_VISIBLE, self.show_settings_dlg) self.window.add_accel_group(accelgroup) if self.options.screenshot: gobject.timeout_add(700, self.do_screenshot) return gobject.idle_add(self.on_idle) def button_released(self, unused_widget, evt): """A mouse button was released.""" if evt.button == 1: self.move_dragged = None return True def button_pressed(self, widget, evt): """A mouse button was pressed.""" self.set_accept_focus(True) if evt.button == 1: self.move_dragged = widget.get_pointer() self.window.set_opacity(self.options.opacity) # remove no_press_timer if self.no_press_timer: gobject.source_remove(self.no_press_timer) self.no_press_timer = None return True def pointer_leave(self, unused_widget, unused_evt): self.set_accept_focus(False) def set_accept_focus(self, accept_focus=True): self.window.set_accept_focus(accept_focus) if accept_focus: logging.debug('window now accepts focus') else: logging.debug('window now does not accept focus') def _window_moved(self): """The window has moved position, save it.""" if not self.move_dragged: return old_p = self.move_dragged new_p = self.window.get_pointer() x, y = self.window.get_position() x, y = x + new_p[0] - old_p[0], y + new_p[1] - old_p[1] self.window.move(x, y) logging.info('Moved window to %d, %d' % (x, y)) self.options.x_pos = x self.options.y_pos = y def on_idle(self): """Check for events on idle.""" event = self.devices.next_event() try: if event: self.handle_event(event) else: for button in self.buttons: button.empty_event() time.sleep(0.001) except KeyboardInterrupt: self.quit_program() return False return True # continue calling def handle_event(self, event): """Handle an X event.""" if event.type == 'EV_MOV': if self.mouse_indicator_win.get_property('visible'): self.mouse_indicator_win.center_on_cursor(*event.value) if self.mouse_follower_win.get_property('visible'): self.mouse_follower_win.center_on_cursor(*event.value) if self.move_dragged: self._window_moved() elif event.type == 'EV_KEY' and event.value in (0, 1): if type(event.code) == str: if event.code.startswith('KEY'): code_num = event.scancode self.handle_key(code_num, event.code, event.value) elif event.code.startswith('BTN'): self.handle_mouse_button(event.code, event.value) if not self.move_dragged: self.reset_no_press_timer() elif event.type.startswith('EV_REL') and event.code == 'REL_WHEEL': self.handle_mouse_scroll(event.value, event.value) elif event.code.startswith('REL'): self.handle_mouse_scroll(event.value, event.value) def reset_no_press_timer(self): """Initialize no_press_timer""" if not self.options.no_press_fadeout: return logging.debug('Resetting no_press_timer') if not self.window.get_property('visible'): self.window.move(self.options.x_pos, self.options.y_pos) self.window.show() self.window.set_opacity(self.options.opacity) if self.no_press_timer: gobject.source_remove(self.no_press_timer) self.no_press_timer = None self.no_press_timer = gobject.timeout_add(int(self.options.no_press_fadeout * 1000), self.no_press_fadeout) def no_press_fadeout(self, begin=True): """Fadeout the window in a second Args: begin: indicate if this timeout is requested by handle_event. """ opacity = self.window.get_opacity() - self.options.opacity / 10.0 if opacity < 0.0: opacity = 0.0; logging.debug('Set opacity = %f' % opacity) self.window.set_opacity(opacity) if opacity == 0.0: self.window.hide() # No need to fade out more self.no_press_timer = None return False if begin: # Recreate a new timer with 0.1 seccond interval self.no_press_timer = gobject.timeout_add(100, self.no_press_fadeout) # The current self.options.no_press_fadeout interval will not be timed # out again. return False def _show_down_key(self, name): """Show the down key. Normally True, unless combo is set. Args: name: name of the key being held down. Returns: True if the key should be shown """ if not self.options.only_combo: return True if self.is_shift_code(name): return True if (any(self.images[img].is_pressed() for img in self.MODS)): return True return False def _handle_event(self, image, name, code): """Handle an event given image and code.""" image.really_pressed = code == 1 if code == 1: if self._show_down_key(name): logging.debug('Switch to %s, code %s' % (name, code)) image.switch_to(name) return # on key up if self.is_shift_code(name): # shift up is always shown if not self.options.sticky_mode: image.switch_to_default() return else: for img in self.MODS: self.images[img].reset_time_if_pressed() image.switch_to_default() def is_shift_code(self, code): if code in ('SHIFT', 'ALT', 'ALTGR', 'CTRL', 'META'): return True return False def handle_key(self, scan_code, xlib_name, value): """Handle a keyboard event.""" code, medium_name, short_name = self.modmap.get_and_check(scan_code, xlib_name) if not code: logging.info('No mapping for scan_code %s', scan_code) return if self.options.scale < 1.0 and short_name: medium_name = short_name logging.debug('Scan code %s, Key %s pressed = %r', scan_code, code, medium_name) if code in self.name_fnames: self._handle_event(self.key_image, code, value) return for keysym, img in (('KEY_SHIFT', 'SHIFT'), ('KEY_CONTROL', 'CTRL'), ('KEY_ALT', 'ALT'), ('KEY_ISO_LEVEL3_SHIFT', 'ALT'), ('KEY_SUPER', 'META')): if code.startswith(keysym): if self.enabled[img]: if keysym == 'KEY_ISO_LEVEL3_SHIFT': self._handle_event(self.images['ALT'], 'ALTGR', value) else: self._handle_event(self.images[img], img, value) return if code.startswith('KEY_KP'): letter = medium_name if code not in self.name_fnames: template = 'one-char-numpad-template' self.name_fnames[code] = [ fix_svg_key_closure(self.svg_name(template), [('&', letter)])] self._handle_event(self.key_image, code, value) return if code.startswith('KEY_'): letter = medium_name if code not in self.name_fnames: logging.debug('code not in %s', code) if len(letter) == 1: template = 'one-char-template' else: template = 'multi-char-template' self.name_fnames[code] = [ fix_svg_key_closure(self.svg_name(template), [('&', letter)])] else: logging.debug('code in %s', code) self._handle_event(self.key_image, code, value) return def handle_mouse_button(self, code, value): """Handle the mouse button event.""" if self.enabled['MOUSE']: if code in self.btns: n_image = 0 n_code = 0 for i, btn in enumerate(self.btns): if btn == code: n_code = i if btn == self.images['MOUSE'].current: n_image = i if self.options.emulate_middle and ((self.images['MOUSE'].current == 'BTN_LEFT' and code == 'BTN_RIGHT') or (self.images['MOUSE'].current == 'BTN_RIGHT' and code == 'BTN_LEFT')): code = 'BTN_MIDDLE' elif value == 0 and n_code != n_image: code = self.btns[n_image - n_code] elif value == 1 and n_image: code = self.btns[n_image | n_code] elif code not in self.name_fnames: btn_num = code.replace('BTN_', '') self.name_fnames[code] = [ fix_svg_key_closure(self.svg_name('mouse'), [('>​', '>' + btn_num)])] self._handle_event(self.images['MOUSE'], code, value) if self.options.visible_click: if value == 1: self.mouse_indicator_win.center_on_cursor() self.mouse_indicator_win.maybe_show() else: self.mouse_indicator_win.fade_away() return True def handle_mouse_scroll(self, direction, unused_value): """Handle the mouse scroll button event.""" if not self.enabled['MOUSE']: return if direction == 'REL_RIGHT': self._handle_event(self.images['MOUSE'], 'REL_RIGHT', 1) elif direction == 'REL_LEFT': self._handle_event(self.images['MOUSE'], 'REL_LEFT', 1) elif direction > 0: self._handle_event(self.images['MOUSE'], 'SCROLL_UP', 1) elif direction < 0: self._handle_event(self.images['MOUSE'], 'SCROLL_DOWN', 1) self.images['MOUSE'].switch_to_default() return True def quit_program(self, *unused_args): """Quit the program.""" self.devices.stop_listening() self.destroy(None) def destroy(self, unused_widget, unused_data=None): """Also quit the program.""" self.devices.stop_listening() self.options.save() gtk.main_quit() def right_click_handler(self, unused_widget, event): """Handle the right click button and show a menu.""" if event.button != 3: return menu = self.create_context_menu() menu.show() menu.popup(None, None, None, event.button, event.time) def create_context_menu(self): """Create a context menu on right click.""" menu = gtk.Menu() toggle_chrome = gtk.CheckMenuItem(_('Window _Chrome')) toggle_chrome.set_active(self.window.get_decorated()) toggle_chrome.connect_object('activate', self.toggle_chrome, self.window.get_decorated()) toggle_chrome.show() menu.append(toggle_chrome) settings_click = gtk.MenuItem(_('_Settings...\tCtrl-S')) settings_click.connect_object('activate', self.show_settings_dlg, None) settings_click.show() menu.append(settings_click) about_click = gtk.MenuItem(_('_About...')) about_click.connect_object('activate', self.show_about_dlg, None) about_click.show() menu.append(about_click) quitcmd = gtk.MenuItem(_('_Quit\tCtrl-Q')) quitcmd.connect_object('activate', self.destroy, None) quitcmd.show() menu.append(quitcmd) return menu def toggle_chrome(self, current): """Toggle whether the window has chrome or not.""" self.window.set_decorated(not current) self.options.decorated = not self.options.decorated def show_settings_dlg(self, *unused_args): """Show the settings dialog.""" dlg = settings.SettingsDialog(self.window, self.options) dlg.connect('settings-changed', self.settings_changed) dlg.show_all() dlg.run() dlg.destroy() def settings_changed(self, unused_dlg): """Event received from the settings dialog.""" for img in self.IMAGES: self._toggle_a_key(self.images[img], img, self.get_option(cstrf(img.lower))) self.create_buttons() self.layout_boxes() self.mouse_indicator_win.hide() self.mouse_indicator_win.timeout = self.options.visible_click_timeout self.window.set_decorated(self.options.decorated) self.name_fnames = self.create_names_to_fnames() self.pixbufs.reset_all(self.name_fnames, self.options.scale) for but in self.buttons: if but.normal != 'KEY_EMPTY': but.reset_image(self.enabled[but.normal.replace('_EMPTY', '')]) else: but.reset_image() if but.normal == 'MOUSE': but.timeout_secs = self.options.mouse_timeout else: but.timeout_secs = self.options.key_timeout # all this to get it to resize smaller x, y = self.window.get_position() self.hbox.resize_children() self.window.resize_children() self.window.reshow_with_initial_size() self.hbox.resize_children() self.event_box.resize_children() self.window.resize_children() self.window.move(x, y) self.update_shape_mask(force=True) # reload keymap self.modmap = mod_mapper.safely_read_mod_map( self.options.kbd_file, self.options.kbd_files) def _toggle_a_key(self, image, name, show): """Toggle show/hide a key.""" if self.enabled[name] == show: return if show: image.showit = True self.enabled[name] = True image.switch_to_default() else: image.showit = False self.enabled[name] = False image.hide() def show_about_dlg(self, *_): dlg = gtk.AboutDialog() # Find the logo file logo_paths = (os.path.join(self.pathname, '../../icons'),) logo_paths += tuple(logo_path + '/share/pixmaps' for logo_path in ( os.path.expanduser('~'), '/usr', '/usr/local', '/opt/local', )) logo_paths = [logo_path + '/key-mon.xpm' for logo_path in logo_paths] for logo_path in logo_paths: if os.path.exists(logo_path): dlg.set_logo(gtk.gdk.pixbuf_new_from_file(logo_path)) break dlg.set_name('Keyboard Status Monitor') dlg.set_program_name('key-mon') dlg.set_website('http://code.google.com/p/key-mon/') dlg.set_version(__version__) dlg.set_authors([ __author__, 'Yu-Jie Lin', 'Danial G. Taylor', 'Jakub Steiner', ]) dlg.set_license('''Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.''') dlg.run() dlg.destroy() def show_version(): """Show the version number and author, used by help2man.""" print _('Keymon version %s.') % __version__ print _('Written by %s') % __author__ def create_options(): opts = options.Options() opts.add_option(opt_short='-s', opt_long='--smaller', dest='smaller', default=False, type='bool', help=_('Make the dialog 25% smaller than normal.')) opts.add_option(opt_short='-l', opt_long='--larger', dest='larger', default=False, type='bool', help=_('Make the dialog 25% larger than normal.')) opts.add_option(opt_short='-m', opt_long='--meta', dest='meta', type='bool', ini_group='buttons', ini_name='meta', default=None, help=_('Show the meta (windows) key.')) opts.add_option(opt_long='--mouse', dest='mouse', type='bool', default=True, ini_group='buttons', ini_name='mouse', help=_('Show the mouse.')) opts.add_option(opt_long='--shift', dest='shift', type='bool', default=True, ini_group='buttons', ini_name='shift', help=_('Show shift key.')) opts.add_option(opt_long='--ctrl', dest='ctrl', type='bool', default=True, ini_group='buttons', ini_name='ctrl', help=_('Show the ctrl key.')) opts.add_option(opt_long='--alt', dest='alt', type='bool', default=True, ini_group='buttons', ini_name='alt', help=_('Show the alt key.')) opts.add_option(opt_long='--scale', dest='scale', type='float', default=1.0, ini_group='ui', ini_name='scale', help=_('Scale the dialog. ex. 2.0 is 2 times larger, 0.5 is ' 'half the size. Defaults to %default')) opts.add_option(opt_long='--key-timeout', dest='key_timeout', type='float', default=0.5, ini_group='ui', ini_name='key_timeout', help=_('Timeout before key returns to unpressed image. ' 'Defaults to %default')) opts.add_option(opt_long='--mouse-timeout', dest='mouse_timeout', type='float', default=0.2, ini_group='ui', ini_name='mouse_timeout', help=_('Timeout before mouse returns to unpressed image. ' 'Defaults to %default')) opts.add_option(opt_long='--visible-click-timeout', dest='visible_click_timeout', type='float', default=0.2, ini_group='ui', ini_name='visible_click_timeout', help=_('Timeout before highly visible click disappears. ' 'Defaults to %default')) opts.add_option(opt_long='--decorated', dest='decorated', type='bool', ini_group='ui', ini_name='decorated', default=False, help=_('Show decoration')) opts.add_option(opt_long='--backgroundless', dest='backgroundless', type='bool', ini_group='ui', ini_name='backgroundless', default=False, help=_('Show only buttons')) opts.add_option(opt_long='--no-press-fadeout', dest='no_press_fadeout', type='float', default=0.0, ini_group='ui', ini_name='no_press_fadeout', help=_('Fadeout the window after a period with no key press. ' 'Defaults to %default seconds (Experimental)')) opts.add_option(opt_long='--only_combo', dest='only_combo', type='bool', ini_group='ui', ini_name='only_combo', default=False, help=_('Show only key combos (ex. Control-A)')) opts.add_option(opt_long='--sticky', dest='sticky_mode', type='bool', ini_group='ui', ini_name='sticky_mode', default=False, help=_('Sticky mode')) opts.add_option(opt_long='--visible_click', dest='visible_click', type='bool', ini_group='ui', ini_name='visible-click', default=False, help=_('Show where you clicked')) opts.add_option(opt_long='--follow_mouse', dest='follow_mouse', type='bool', ini_group='ui', ini_name='follow-mouse', default=False, help=_('Show the mouse more visibly')) opts.add_option(opt_long='--kbdfile', dest='kbd_file', ini_group='devices', ini_name='map', default=None, help=_('Use this kbd filename.')) opts.add_option(opt_long='--swap', dest='swap_buttons', type='bool', default=False, ini_group='devices', ini_name='swap_buttons', help=_('Swap the mouse buttons.')) opts.add_option(opt_long='--emulate-middle', dest='emulate_middle', type='bool', default=False, ini_group='devices', ini_name='emulate_middle', help=_('When you press the left, and right mouse buttons at the same time, ' 'it displays as a middle mouse button click. ')) opts.add_option(opt_short='-v', opt_long='--version', dest='version', type='bool', help=_('Show version information and exit.')) opts.add_option(opt_short='-t', opt_long='--theme', dest='theme', type='str', ini_group='ui', ini_name='theme', default='classic', help=_('The theme to use when drawing status images (ex. "-t apple").')) opts.add_option(opt_long='--list-themes', dest='list_themes', type='bool', help=_('List available themes')) opts.add_option(opt_long='--old-keys', dest='old_keys', type='int', ini_group='buttons', ini_name='old-keys', help=_('How many historical keypresses to show (defaults to %default)'), default=0) opts.add_option(opt_long='--reset', dest='reset', type='bool', help=_('Reset all options to their defaults.'), default=None) opts.add_option(opt_short=None, opt_long='--opacity', type='float', dest='opacity', default=1.0, help='Opacity of window', ini_group='ui', ini_name='opacity') opts.add_option(opt_short=None, opt_long=None, type='int', dest='x_pos', default=-1, help='Last X Position', ini_group='position', ini_name='x') opts.add_option(opt_short=None, opt_long=None, type='int', dest='y_pos', default=-1, help='Last Y Position', ini_group='position', ini_name='y') opts.add_option_group(_('Developer Options'), _('These options are for developers.')) opts.add_option(opt_long='--loglevel', dest='loglevel', type='str', default='', help=_('Logging level')) opts.add_option(opt_short='-d', opt_long='--debug', dest='debug', type='bool', default=False, help=_('Output debugging information. ' 'Shorthand for --loglevel=debug')) opts.add_option(opt_long='--screenshot', dest='screenshot', type='str', default='', help=_('Create a "screenshot.png" and exit. ' 'Pass a comma separated list of keys to simulate' '(ex. "KEY_A,KEY_LEFTCTRL").')) return opts def main(): """Run the program.""" # Check for --loglevel, --debug, we deal with them by ourselves because # option parser also use logging. loglevel = None for idx, arg in enumerate(sys.argv): if '--loglevel' in arg: if '=' in arg: loglevel = arg.split('=')[1] else: loglevel = sys.argv[idx + 1] level = getattr(logging, loglevel.upper(), None) if level is None: raise ValueError('Invalid log level: %s' % loglevel) loglevel = level else: if '--debug' in sys.argv or '-d' in sys.argv: loglevel = logging.DEBUG logging.basicConfig( level=loglevel, format='%(filename)s [%(lineno)d]: %(levelname)s %(message)s') if loglevel is None: # Disabling warning, info, debug messages logging.disable(logging.WARNING) opts = create_options() opts.read_ini_file(os.path.join(settings.get_config_dir(), 'config')) desc = _('Usage: %prog [Options...]') opts.parse_args(desc, sys.argv) if opts.version: show_version() sys.exit(0) if opts.smaller: opts.scale = 0.75 elif opts.larger: opts.scale = 1.25 opts.themes = settings.get_themes() if opts.list_themes: print _('Available themes:') print theme_names = sorted(opts.themes) name_len = max(len(name) for name in theme_names) for theme in theme_names: print (' - %%-%ds: %%s' % name_len) % (theme, opts.themes[theme][0]) raise SystemExit() elif opts.theme and opts.theme not in opts.themes: print _('Theme %r does not exist') % opts.theme print print _('Please make sure %r can be found in ' 'one of the following directories:') % opts.theme print for theme_dir in settings.get_config_dirs('themes'): print ' - %s' % theme_dir sys.exit(-1) if opts.reset: print _('Resetting to defaults.') opts.reset_to_defaults() opts.save() keymon = KeyMon(opts) try: gtk.main() except KeyboardInterrupt: keymon.quit_program() if __name__ == '__main__': #import cProfile #cProfile.run('main()', 'keymonprof') main() key-mon-1.17/src/keymon/xlib.py0000750006766500116100000001727012130344127020142 0ustar scottkirkwoodeng00000000000000#!/usr/bin/python # # Copyright 2010 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Library to get X events from Record. This is designed to read events from X windows for keyboard and mouse events. """ __author__ = 'Scott Kirkwood (scott+keymon@forusers.com)' from Xlib import display from Xlib import X from Xlib import XK from Xlib.ext import record from Xlib.protocol import rq import locale import sys import time import threading import collections class XEvent(object): """An event, mimics edev.py events.""" def __init__(self, atype, scancode, code, value): self._type = atype self._scancode = scancode self._code = code self._value = value def get_type(self): """Get the type of event.""" return self._type type = property(get_type) def get_scancode(self): """Get the scancode if any.""" return self._scancode scancode = property(get_scancode) def get_code(self): """Get the code string.""" return self._code code = property(get_code) def get_value(self): """Get the value 0 for up, 1 for down, etc.""" return self._value value = property(get_value) def __str__(self): return 'type:%s scancode:%s code:%s value:%s' % (self._type, self._scancode, self._code, self._value) class XEvents(threading.Thread): """A thread to queue up X window events from RECORD extension.""" _butn_to_code = { 1: 'BTN_LEFT', 2: 'BTN_MIDDLE', 3: 'BTN_RIGHT', 4: 'REL_WHEEL', 5: 'REL_WHEEL', 6: 'REL_LEFT', 7: 'REL_RIGHT'} def __init__(self): threading.Thread.__init__(self) self.setDaemon(True) self.setName('Xlib-thread') self._listening = False self.record_display = display.Display() self.local_display = display.Display() self.ctx = None self.keycode_to_symbol = collections.defaultdict(lambda: 'KEY_DUNNO') self._setup_lookup() self.events = [] # each of type XEvent def run(self): """Standard run method for threading.""" self.start_listening() def _setup_lookup(self): """Setup the key lookups.""" # set locale to default C locale, see Issue 77. # Use setlocale(None) to get curent locale instead of getlocal. # See Issue 125 and http://bugs.python.org/issue1699853. OLD_CTYPE = locale.setlocale(locale.LC_CTYPE, None) locale.setlocale(locale.LC_CTYPE, 'C') for name in dir(XK): if name[:3] == "XK_": code = getattr(XK, name) self.keycode_to_symbol[code] = 'KEY_' + name[3:].upper() locale.setlocale(locale.LC_CTYPE, OLD_CTYPE) self.keycode_to_symbol[65027] = 'KEY_ISO_LEVEL3_SHIFT' self.keycode_to_symbol[269025062] = 'KEY_BACK' self.keycode_to_symbol[269025063] = 'KEY_FORWARD' self.keycode_to_symbol[16777215] = 'KEY_CAPS_LOCK' self.keycode_to_symbol[269025067] = 'KEY_WAKEUP' # Multimedia keys self.keycode_to_symbol[269025042] = 'KEY_AUDIOMUTE' self.keycode_to_symbol[269025041] = 'KEY_AUDIOLOWERVOLUME' self.keycode_to_symbol[269025043] = 'KEY_AUDIORAISEVOLUME' self.keycode_to_symbol[269025047] = 'KEY_AUDIONEXT' self.keycode_to_symbol[269025044] = 'KEY_AUDIOPLAY' self.keycode_to_symbol[269025046] = 'KEY_AUDIOPREV' self.keycode_to_symbol[269025045] = 'KEY_AUDIOSTOP' # Turkish / F layout self.keycode_to_symbol[699] = 'KEY_GBREVE' # scancode = 26 / 18 self.keycode_to_symbol[697] = 'KEY_IDOTLESS' # scancode = 23 / 19 self.keycode_to_symbol[442] = 'KEY_SCEDILLA' # scancode = 39 / 40 def next_event(self): """Returns the next event in queue, or None if none.""" if self.events: return self.events.pop(0) return None def start_listening(self): """Start listening to RECORD extension and queuing events.""" if not self.record_display.has_extension("RECORD"): print "RECORD extension not found" sys.exit(1) self._listening = True self.ctx = self.record_display.record_create_context( 0, [record.AllClients], [{ 'core_requests': (0, 0), 'core_replies': (0, 0), 'ext_requests': (0, 0, 0, 0), 'ext_replies': (0, 0, 0, 0), 'delivered_events': (0, 0), 'device_events': (X.KeyPress, X.MotionNotify), # why only two, it's a range? 'errors': (0, 0), 'client_started': False, 'client_died': False, }]) self.record_display.record_enable_context(self.ctx, self._handler) # Don't understand this, how can we free the context yet still use it in Stop? self.record_display.record_free_context(self.ctx) self.record_display.close() def stop_listening(self): """Stop listening to events.""" if not self._listening: return self.local_display.record_disable_context(self.ctx) self.local_display.flush() self.local_display.close() self._listening = False self.join(0.05) def listening(self): """Are you listening?""" return self._listening def _handler(self, reply): """Handle an event.""" if reply.category != record.FromServer: return if reply.client_swapped: return data = reply.data while len(data): event, data = rq.EventField(None).parse_binary_value( data, self.record_display.display, None, None) if event.type == X.ButtonPress: self._handle_mouse(event, 1) elif event.type == X.ButtonRelease: self._handle_mouse(event, 0) elif event.type == X.KeyPress: self._handle_key(event, 1) elif event.type == X.KeyRelease: self._handle_key(event, 0) elif event.type == X.MotionNotify: self._handle_mouse(event, 2) else: print event def _handle_mouse(self, event, value): """Add a mouse event to events. Params: event: the event info value: 2=motion, 1=down, 0=up """ if value == 2: self.events.append(XEvent('EV_MOV', 0, 0, (event.root_x, event.root_y))) elif event.detail in [4, 5]: if event.detail == 5: value = -1 else: value = 1 self.events.append(XEvent('EV_REL', 0, XEvents._butn_to_code.get(event.detail, 'BTN_%d' % event.detail), value)) else: self.events.append(XEvent('EV_KEY', 0, XEvents._butn_to_code.get(event.detail, 'BTN_%d' % event.detail), value)) def _handle_key(self, event, value): """Add key event to events. Params: event: the event info value: 1=down, 0=up """ keysym = self.local_display.keycode_to_keysym(event.detail, 0) if keysym not in self.keycode_to_symbol: print 'Missing code for %d = %d' % (event.detail - 8, keysym) self.events.append(XEvent('EV_KEY', event.detail - 8, self.keycode_to_symbol[keysym], value)) def _run_test(): """Run a test or debug session.""" events = XEvents() events.start() while not events.listening(): time.sleep(1) print 'Waiting for initializing...' print 'Press ESCape to quit' try: while events.listening(): try: evt = events.next_event() except KeyboardInterrupt: print 'User interrupted' events.stop_listening() if evt: print evt if evt.code == 'KEY_ESCAPE': events.stop_listening() finally: events.stop_listening() if __name__ == '__main__': _run_test() key-mon-1.17/src/keymon/settings.py0000750006766500116100000002467312130344127021051 0ustar scottkirkwoodeng00000000000000#!/usr/bin/python # # Copyright 2010 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Settings dialog and related functions.""" __author__ = 'scott@forusers.com (Scott Kirkwood)' import gettext import gobject import gtk import logging import os from ConfigParser import SafeConfigParser LOG = logging.getLogger('settings') class SettingsDialog(gtk.Dialog): """Create a settings/preferences dialog for keymon.""" __gproperties__ = {} __gsignals__ = { 'settings-changed' : ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()) } def __init__(self, unused_view, options): gtk.Dialog.__init__(self, title='Preferences', parent=None, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT | gtk.WIN_POS_MOUSE, buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)) self.options = options self.set_default_size(350, 350) self.connect('response', self._response) self.notebook = gtk.Notebook() self.vbox.pack_start(self.notebook) buttons = ButtonsFrame(self) self.notebook.append_page(buttons, gtk.Label(_('Buttons'))) misc = MiscFrame(self) self.notebook.append_page(misc, gtk.Label(_('Misc'))) self.notebook.show() self.show() def settings_changed(self): """Emit the settings changed message to parent.""" self.emit('settings-changed') def _response(self, unused_dialog, response_id): """Wait for the close response.""" if response_id == gtk.RESPONSE_CLOSE: LOG.info('Close in _Response.') self.destroy() @classmethod def register(cls): """Register this class as a Gtk widget.""" gobject.type_register(SettingsDialog) class CommonFrame(gtk.Frame): """Stuff common to several frames.""" def __init__(self, settings): gtk.Frame.__init__(self) self.settings = settings self.create_layout() def create_layout(self): """Do nothing.""" pass def _add_check(self, vbox, title, tooltip, option): """Add a check button.""" check_button = gtk.CheckButton(label=title) val = getattr(self.settings.options, option) logging.info('got option %s as %s', option, val) if val: check_button.set_active(True) else: check_button.set_active(False) check_button.connect('toggled', self._toggled, option) check_button.set_tooltip_text(tooltip) vbox.pack_start(check_button, False, False) def _add_dropdown(self, vbox, title, tooltip, opt_lst, option, width_char=-1): """Add a drop down box.""" hbox = gtk.HBox() label = gtk.Label(title) label.set_tooltip_text(tooltip) hbox.pack_start(label, expand=False, fill=False) combo = gtk.combo_box_entry_new_text() combo.child.set_width_chars(width_char) for opt in opt_lst: combo.append_text(str(opt)) val = getattr(self.settings.options, option) if isinstance(val, float): str_val = '%0.3g' % val else: str_val = val try: index = opt_lst.index(str_val) except ValueError: index = 0 combo.set_active(index) combo.set_tooltip_text(tooltip) hbox.pack_start(combo, expand=False, fill=False, padding=10) logging.info('got option %s as %s', option, val) combo.connect('changed', self._combo_changed, option) vbox.pack_start(hbox, expand=False, fill=False) return combo def _toggled(self, widget, option): """The checkbox was toggled.""" if widget.get_active(): val = 1 else: val = 0 self._update_option(option, val, str(val)) def _combo_changed(self, widget, option): """The combo box changed.""" val = widget.get_active() str_val = widget.get_active_text() self._update_option(option, val, str_val) def _update_option(self, option, val, str_val): """Update an option.""" if str_val.isdigit(): setattr(self.settings.options, option, val) LOG.info('Set option %s to %s' % (option, val)) else: setattr(self.settings.options, option, str_val) LOG.info('Set option %s to %s' % (option, str_val)) self.settings.options.save() self.settings.settings_changed() class MiscFrame(CommonFrame): """The miscellaneous frame.""" def __init__(self, settings): CommonFrame.__init__(self, settings) def create_layout(self): """Create the box's layout.""" vbox = gtk.VBox() self._add_check( vbox, _('Swap left-right mouse buttons'), _('Swap the left and the right mouse buttons'), 'swap_buttons') self._add_check( vbox, _('Left+right buttons emulates middle mouse button'), _('Clicking both mouse buttons emulates the middle mouse button.'), 'emulate_middle') self._add_check( vbox, _('Highly visible click'), _('Show a circle when the users clicks.'), 'visible_click') self._add_check( vbox, _('Window decoration'), _('Show the normal windows borders'), 'decorated') self._add_check( vbox, _('Window backgroundless'), _('Show only the buttons'), 'backgroundless') self._add_check( vbox, _('Only key combinations'), _('Show a key only when used with a modifier key (like Control)'), 'only_combo') self._add_check( vbox, _('StickyKeys mode'), _('Make modifier keys be sticky'), 'sticky_mode') sizes = ['1.0', '0.6', '0.8', '1.0', '1.2', '1.4', '1.6', '1.8'] self._add_dropdown( vbox, _('Scale:'), _('How much larger or smaller than normal to make key-mon. ' 'Where 1.0 is normal sized.'), sizes, 'scale', 4) timeouts = ['0.2', '0.4', '0.5', '0.6', '0.8', '1.0', '1.2', '1.4', '1.6', '1.8', '2.0', '2.5', '3.0', '3.5', '4.0'] self._add_dropdown( vbox, _('Key timeout:'), _('How long before activated key buttons disappear. ' 'Default is 0.5'), timeouts, 'key_timeout', 4) self._add_dropdown( vbox, _('Mouse timeout:'), _('How long before activated mouse buttons disappear. ' 'Default is 0.2'), timeouts, 'mouse_timeout', 4) self._add_dropdown( vbox, _('Highly visible click timeout:'), _('How long before highly visible click disappear. ' 'Default is 0.2'), timeouts, 'visible_click_timeout', 4) self.themes = self.settings.options.themes.keys() self._add_dropdown( vbox, _('Themes:'), _('Which theme of buttons to show (ex. Apple)'), self.themes, 'theme') self.kbd_files = sorted(list(set( os.path.basename(kbd) for kbd in self.settings.options.kbd_files))) self._add_dropdown( vbox, _('Keymap:'), _('Which keymap file to use'), self.kbd_files, 'kbd_file') self.add(vbox) class ButtonsFrame(CommonFrame): """The buttons frame.""" def __init__(self, settings): """Create common frame.""" CommonFrame.__init__(self, settings) def create_layout(self): """Create the layout for buttons.""" vbox = gtk.VBox() self._add_check( vbox, _('_Mouse'), _('Show the mouse.'), 'mouse') self._add_check( vbox, _('_Shift'), _('Show the shift key when pressed.'), 'shift') self._add_check( vbox, _('_Ctrl'), _('Show the Control key when pressed.'), 'ctrl') self._add_check( vbox, _('Meta (_windows keys)'), _('Show the Window\'s key (meta key) when pressed.'), 'meta') self._add_check( vbox, _('_Alt'), _('Show the Alt key when pressed.'), 'alt') self._add_dropdown( vbox, _('Old Keys:'), _('When typing fast show more than one key typed.'), [0, 1, 2, 3, 4], 'old_keys') self.add(vbox) def _test_settings_changed(unused_widget): """Help to test if the settings change message is received.""" print 'Settings changed' def manually_run_dialog(): """Test the dialog without starting keymon.""" import key_mon SettingsDialog.register() gettext.install('key_mon', 'locale') logging.basicConfig( level=logging.DEBUG, format = '%(filename)s [%(lineno)d]: %(levelname)s %(message)s') options = key_mon.create_options() options.read_ini_file('~/.config/key-mon/config') dlg = SettingsDialog(None, options) dlg.connect('settings-changed', _test_settings_changed) dlg.show_all() dlg.run() return 0 def get_config_dir(): """Return the base directory of configuration.""" return os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')) + '/key-mon' def get_config_dirs(kind): """Return search paths of certain kind of configuration directory. Args: kind: Subfolder name Return: List of full paths """ config_dirs = [d for d in ( os.path.join(get_config_dir(), kind), os.path.join(os.path.dirname(os.path.abspath(__file__)), kind)) \ if os.path.exists(d)] return config_dirs def get_themes(): """Return a dict of themes. keys are theme names values are tuples of (description, path) path is where the theme directory located, i.e. theme files are path/*. """ theme_dirs = get_config_dirs('themes') themes = {} for theme_dir in theme_dirs: for entry in sorted(os.listdir(theme_dir)): try: parser = SafeConfigParser() theme_config = os.path.join(theme_dir, entry, 'config') parser.read(theme_config) desc = parser.get('theme', 'description') if entry not in themes: themes[entry] = (desc, os.path.join(theme_dir, entry)) except: LOG.warning(_('Unable to read theme %r') % (theme_config)) return themes def get_kbd_files(): """Return a list of kbd file paths""" config_dirs = get_config_dirs('') kbd_files = [ os.path.join(d, f) \ for d in config_dirs \ for f in sorted(os.listdir(d)) if f.endswith('.kbd')] return kbd_files if __name__ == '__main__': manually_run_dialog() key-mon-1.17/src/keymon/two_state_image.py0000750006766500116100000000744712130344127022364 0ustar scottkirkwoodeng00000000000000#!/usr/bin/python # # Copyright 2010 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Image that defaults back to a default state after a while. You can switch the image to something else but it defaults back to the default image (the first image) after calling EmptyEvent() a few times """ __author__ = 'scott@forusers.com (Scott Kirkwood))' import pygtk pygtk.require('2.0') import gtk import time DEFAULT_TIMEOUT_SECS = 0.5 class TwoStateImage(gtk.Image): """Image has a default image (say a blank image) which it goes back to. It can also pass the information down to another image.""" def __init__(self, pixbufs, normal, show=True, defer_to=None): gtk.Image.__init__(self) self.pixbufs = pixbufs self.normal = normal self.count_down = None self.showit = show self.current = '' self.defer_to = defer_to self.timeout_secs = DEFAULT_TIMEOUT_SECS self.switch_to(self.normal) self._really_pressed = False def reset_image(self, showit=True): """Image from pixbufs has changed, reset.""" self.showit = showit self._switch_to(self.normal) self.showit = True def is_pressed(self): return self.current != self.normal def get_really_pressed(self): "Get the pressing state if a key is physically pressed." return self._really_pressed def set_really_pressed(self, value): """Set if a key is physically pressed. This is different than is_pressed(), which is the pressing state of indicator, not reflect the real key pressing state. Should be set when key event comes in. """ self._really_pressed = value # Lint doesn't like @property.setter because of duplicate method names. really_pressed = property(get_really_pressed, set_really_pressed, None, "Physically pressed button") def reset_time_if_pressed(self): """Start the countdown now.""" if self.is_pressed(): self.count_down = time.time() def switch_to(self, name): """Switch to image with this name.""" if self.current != self.normal and self.defer_to: self._defer_to(self.current) # Make sure defer_to image will only start counting timeout after self # image has timed out. if self.count_down: self.defer_to.count_down = self.count_down + self.timeout_secs else: self.defer_to.count_down += self.timeout_secs self._switch_to(name) def _switch_to(self, name): """Internal, switch to image with this name even if same.""" self.set_from_pixbuf(self.pixbufs.get(name)) self.current = name self.count_down = None if self.showit: self.show() def switch_to_default(self): """Switch to the default image.""" self.count_down = time.time() def empty_event(self): """Sort of a idle event. Returns True if image has been changed. """ if self.count_down is None: return delta = time.time() - self.count_down if delta > self.timeout_secs: if self.normal.replace('_EMPTY', '') in ('SHIFT', 'ALT', 'CTRL', 'META') and \ self.really_pressed: return self.count_down = None self._switch_to(self.normal) return True def _defer_to(self, old_name): """If possible the button is passed on.""" if not self.defer_to: return self.defer_to.switch_to(old_name) self.defer_to.switch_to_default() key-mon-1.17/src/keymon/options_test.py0000750006766500116100000001262012130344127021730 0ustar scottkirkwoodeng00000000000000#!/usr/bin/python # # Copyright 2010 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import unittest import options import StringIO class TestOptionItem(unittest.TestCase): def test_create_int(self): x = options.OptionItem( dest='x', _type='int', default=-99, name='namex', help='helpx', opt_group='opt-group', opt_short='-x', opt_long='--xlong', ini_group='ini_group', ini_name='ini_name') self.assertEqual(x.value, -99) x.value = 2 self.assertEqual(x.value, 2) self.assertEqual(x.type, 'int') self.assertEqual(x.name, 'namex') self.assertEqual(x.help, 'helpx') self.assertEqual(x.opt_group, 'opt-group') self.assertEqual(x.opt_short, '-x') self.assertEqual(x.opt_long, '--xlong') self.assertEqual(x.ini_group, 'ini_group') self.assertEqual(x.ini_name, 'ini_name') def test_create_bool_false(self): x = options.OptionItem( dest='x', _type='bool', default=False, name='namex', help='helpx', opt_group='opt-group', opt_short='-x', opt_long='--xlong', ini_group='group', ini_name='section') self.assertFalse(x.value) x.value = True self.assertTrue(x.value) x.value = 0 self.assertFalse(x.value) x.value = 1 self.assertTrue(x.value) x.value = None self.assertEqual(x.value, None) x.value = 'TrUe' self.assertTrue(x.value) x.value = 'FaLsE' self.assertFalse(x.value) x.value = 'On' self.assertTrue(x.value) x.value = 'off' self.assertFalse(x.value) x.value = 'yeS' self.assertTrue(x.value) x.value = 'no' self.assertFalse(x.value) def test_create_bool_none(self): x = options.OptionItem( opt_short='-x', opt_long='--xx', ini_group='group', ini_name='section', dest='x', name='variable', help='variable help', _type='bool', default=None) self.assertEqual(x.value, None) x.value = 0 self.assertFalse(x.value) x.value = 1 self.assertTrue(x.value) class TestOptions(unittest.TestCase): def setUp(self): self.options = options.Options() self.options.add_option('x', 'bool', None, name='x variable', help='Help Varaible', opt_short='-x', opt_long='--xx', ini_group='options', ini_name='x') self.options.add_option('tr', 'bool', True, name='def true', help='Defaults to true', opt_short='-t', opt_long='--true', ini_group='options', ini_name='true') self.options.add_option('fa', 'bool', False, name='false variable', help='Defaults to false', opt_short='-f', opt_long='--false', ini_group='options', ini_name='false') self.options.add_option('num', 'int', None, name='num none', help='Number that returns None by default', opt_short='-n', opt_long='--num', ini_group='ints', ini_name='num') self.options.add_option('num99', 'int', 99, name='num 99', help='Number that defaults to 99', opt_short=None, opt_long='--num99', ini_group='ints', ini_name='num99') def test_optparse(self): args = ['-x', '--true', '--num', '123'] self.options.parse_args("Usage:", args) o = self.options self.assertTrue(o.x) self.assertTrue(o.tr) self.assertFalse(o.fa) self.assertEqual(o.num, 123) self.assertEqual(o.num99, 99) def test_from_ini(self): lines = [] lines.append('[ints]') lines.append('num99 = 932') lines.append('num = 345') lines.append('') lines.append('[options]') lines.append('x = 0') lines.append('true = 0') lines.append('false = 1') io = StringIO.StringIO('\n'.join(lines)) self.options.parse_ini(io) self.options.parse_args("Usage", []) o = self.options self.assertFalse(o.x) self.assertFalse(o.tr) self.assertTrue(o.fa) self.assertEqual(o.num, 345) self.assertEqual(o.num99, 932) def test_override_ini(self): lines = [] lines.append('[ints]') lines.append('num99 = 932') lines.append('num = 345') lines.append('') lines.append('[options]') lines.append('x = 0') lines.append('true = 0') lines.append('false = 1') io = StringIO.StringIO('\n'.join(lines)) self.options.parse_ini(io) args = [ '--num99', '99', '--num', '456', '--true', '-x', '--nofalse', ] self.options.parse_args("Usage", args) o = self.options self.assertTrue(o.x) self.assertTrue(o.tr) self.assertFalse(o.fa) self.assertEqual(o.num, 456) self.assertEqual(o.num99, 99) def test_to_ini_empty(self): io = StringIO.StringIO() self.options.write_ini(io) contents = io.getvalue() lines = [] lines.append('[options]') lines.append('true = 1') lines.append('false = 0') lines.append('') lines.append('[ints]') lines.append('num99 = 99') lines.append('') lines.append('') self.assertEquals('\n'.join(lines), contents) if __name__ == '__main__': unittest.main() key-mon-1.17/src/keymon/de.kbd0000640006766500116100000001016412130344127017675 0ustar scottkirkwoodeng00000000000000# This is a space separated file with UTF-8 encoding # Short name is optional, will default to the medium-name # Scancode Map-Name Medium-Name Short-Name 1 KEY_ESCAPE Esc 2 KEY_1 1 3 KEY_2 2 4 KEY_3 3 5 KEY_4 4 6 KEY_5 5 7 KEY_6 6 8 KEY_7 7 9 KEY_8 8 10 KEY_9 9 11 KEY_0 0 12 KEY_MINUS ß 13 KEY_EQUAL ' 14 KEY_BACKSPACE Back ⇽ 15 KEY_TAB Tab 16 KEY_Q Q 17 KEY_W W 18 KEY_E E 19 KEY_R R 20 KEY_T T 21 KEY_Y Z 22 KEY_U U 23 KEY_I I 24 KEY_O O 25 KEY_P P 26 KEY_BRACKETLEFT Ü 27 KEY_BRACKETRIGHT + 28 KEY_RETURN Return ⏎ 29 KEY_CONTROL_L Strg STRG 30 KEY_A A 31 KEY_S S 32 KEY_D D 33 KEY_F F 34 KEY_G G 35 KEY_H H 36 KEY_J J 37 KEY_K K 38 KEY_L L 39 KEY_SEMICOLON Ö 40 KEY_APOSTROPHE Ä 41 KEY_GRAVE ^ 42 KEY_SHIFT_L Shift Shft 43 KEY_BACKSLASH # 44 KEY_Z Y 45 KEY_X X 46 KEY_C C 47 KEY_V V 48 KEY_B B 49 KEY_N N 50 KEY_M M 51 KEY_COMMA , 52 KEY_PERIOD . 53 KEY_SLASH - 54 KEY_SHIFT_R Shift Shft 55 KEY_KP_MULTIPLY * 56 KEY_ALT_L Alt 57 KEY_SPACE Space Spc 58 KEY_MULTI_KEY Multi Mul 59 KEY_F1 F1 60 KEY_F2 F2 61 KEY_F3 F3 62 KEY_F4 F4 63 KEY_F5 F5 64 KEY_F6 F6 65 KEY_F7 F7 66 KEY_F8 F8 67 KEY_F9 F9 68 KEY_F10 F10 69 KEY_NUM_LOCK Num 70 KEY_SCROLL_LOCK Rollen 71 KEY_KP_HOME 7 72 KEY_KP_UP 8 73 KEY_KP_PRIOR 9 74 KEY_KP_SUBTRACT - 75 KEY_KP_LEFT 4 76 KEY_KP_BEGIN 5 77 KEY_KP_RIGHT 6 78 KEY_KP_ADD + 79 KEY_KP_END 1 80 KEY_KP_DOWN 2 81 KEY_KP_PAGE_DOWN 3 82 KEY_KP_INSERT 0 83 KEY_KP_DELETE . 84 KEY_ISO_LEVEL3_SHIFT AltGr 86 KEY_LESS < 87 KEY_L1 F11 88 KEY_L2 F12 90 KEY_KATAKANA KATAKANA 91 KEY_HIRAGANA HIRAGANA 92 KEY_HENKAN_MODE HENKAN_MODE 93 KEY_HIRAGANA_KATAKANA HIRAGANA_KATAKANA 94 KEY_MUHENKAN MUHENKAN 96 KEY_KP_ENTER ⏎ 97 KEY_CONTROL_R Strg 98 KEY_KP_DIVIDE / 99 KEY_PRINT Druck 100 KEY_ISO_LEVEL3_SHIFT AltGr 101 KEY_LINEFEED Lf Lf 102 KEY_HOME Pos1 Hm 103 KEY_UP ↑ 104 KEY_PRIOR Bild↑ 105 KEY_LEFT ← 106 KEY_RIGHT → 107 KEY_END Ende 108 KEY_DOWN ↓ 109 KEY_DOWN Bild↓ 110 KEY_INSERT Einfg 111 KEY_DELETE Entf 113 KEY_AUDIOMUTE Mute Mute 114 KEY_AUDIOLOWERVOLUME Vol+ V- 115 KEY_AUDIORAISEVOLUME Vol- V+ 116 KEY_POWEROFF Off Off 117 KEY_KP_EQUAL = 118 KEY_PLUSMINUS +/- 119 KEY_PAUSE Pause Ps 121 KEY_KP_DECIMAL . 122 KEY_HANGUL HANGUL 123 KEY_HANGUL_HANJA HANGUL_HANJA 125 KEY_SUPER_L Super Spr 126 KEY_SUPER_R Super Spr 127 KEY_MENU Menu Men 128 KEY_CANCEL Cancel Can 129 KEY_REDO Redo Red 130 KEY_SUNPROPS Sunprops 131 KEY_UNDO Undo Und 132 KEY_SUNFRONT Sunfront 133 KEY_COPY Copy Cp 134 KEY_SUNOPEN SunOpen 135 KEY_PASTE Paste 136 KEY_FIND Find 137 KEY_CUT Cut Cut 138 KEY_HELP Help 139 KEY_MENUKB MenuKb MenuKb 140 KEY_CALCULATOR Calc 142 KEY_SLEEP Sleep 143 KEY_WAKEUP Fn 144 KEY_EXPLORER Explorer 145 KEY_SEND Send 147 KEY_XFER Xfer 148 KEY_LAUNCH1 Launch1 149 KEY_LAUNCH2 Launch2 150 KEY_WWW www 151 KEY_DOS Dos 152 KEY_SCREENSAVER Screensaver 154 KEY_ROTATEWINDOWS RotateWin 155 KEY_MAIL Mail 156 KEY_FAVORITES Fav 157 KEY_MYCOMPUTER MyComputer 158 KEY_BACK ⇐ 159 KEY_FORWARD ⇒ 161 KEY_EJECT Eject 162 KEY_EJECT Eject 163 KEY_AUDIONEXT Next 164 KEY_AUDIOPLAY Play 165 KEY_AUDIOPREV Prev 166 KEY_AUDIOSTOP Stop 167 KEY_AUDIORECORD Record 168 KEY_AUDIOREWIND Rewind 169 KEY_PHONE Phone 171 KEY_TOOLS Tools 172 KEY_HOMEPAGE HomePage 173 KEY_RELOAD Reload 174 KEY_CLOSE Close 177 KEY_SCROLLUP ScrollUp 178 KEY_SCROLLDOWN ScrollDn 179 KEY_PARENLEFT ( 180 KEY_PARENRIGHT ) 181 KEY_NEW New 182 KEY_REDO Redo Red 195 KEY_MODE_SWITCH Mode 196 KEY_NOSYMBOL - 197 KEY_NOSYMBOL - 198 KEY_NOSYMBOL - 199 KEY_NOSYMBOL - 200 KEY_AUDIOPLAY Play 201 KEY_AUDIOPAUSE Pause 202 KEY_LAUNCH3 Launch3 203 KEY_LAUNCH4 Launch4 205 KEY_SUSPEND Suspend 206 KEY_CLOSE Close 207 KEY_AUDIOPLAY Play 208 KEY_FORWARD Forward 210 KEY_PRINT Druck 212 KEY_WEBCAM WebCam 215 KEY_MAIL Mail 217 KEY_SEARCH Search 219 KEY_FINANCE Finance 221 KEY_SHOP Shop 223 KEY_CANCEL Cancel Can 224 KEY_MONBRIGHTNESSDOWN BrightnessDown 225 KEY_MONBRIGHTNESSUP BrightnessUp 226 KEY_AUDIOMEDIA AudioMedia 227 KEY_DISPLAY Display 228 KEY_KBDLIGHTONOFF LightOnOff 229 KEY_KBDBRIGHTNESSDOWN BrightnessDown 230 KEY_KBDBRIGHTNESSUP BrightnessUp 231 KEY_SEND Send 232 KEY_REPLY Reply 233 KEY_MAILFORWARD MailForward 234 KEY_SAVE Save 235 KEY_DOCUMENTS Docs 236 KEY_BATTERY Battery 237 KEY_BLUETOOTH Bluetooth 238 KEY_WLAN Lan key-mon-1.17/src/keymon/us.kbd0000640006766500116100000001022212130344127017727 0ustar scottkirkwoodeng00000000000000# This is a space separated file with UTF-8 encoding # Short name is optional, will default to the medium-name # Scancode Map-Name Medium-Name Short-Name 1 KEY_ESCAPE Esc 2 KEY_1 1 3 KEY_2 2 4 KEY_3 3 5 KEY_4 4 6 KEY_5 5 7 KEY_6 6 8 KEY_7 7 9 KEY_8 8 10 KEY_9 9 11 KEY_0 0 12 KEY_MINUS - 13 KEY_EQUAL = 14 KEY_BACKSPACE Back ⇽ 15 KEY_TAB Tab 16 KEY_Q Q 17 KEY_W W 18 KEY_E E 19 KEY_R R 20 KEY_T T 21 KEY_Y Y 22 KEY_U U 23 KEY_I I 24 KEY_O O 25 KEY_P P 26 KEY_BRACKETLEFT [ 27 KEY_BRACKETRIGHT ] 28 KEY_RETURN Return ⏎ 29 KEY_CONTROL_L Ctrl Ctl 30 KEY_A A 31 KEY_S S 32 KEY_D D 33 KEY_F F 34 KEY_G G 35 KEY_H H 36 KEY_J J 37 KEY_K K 38 KEY_L L 39 KEY_SEMICOLON ; 40 KEY_QUOTERIGHT ' 41 KEY_QUOTELEFT ` 42 KEY_SHIFT_L Shift Shft 43 KEY_BACKSLASH \ 44 KEY_Z Z 45 KEY_X X 46 KEY_C C 47 KEY_V V 48 KEY_B B 49 KEY_N N 50 KEY_M M 51 KEY_COMMA , 52 KEY_PERIOD . 53 KEY_SLASH / 54 KEY_SHIFT_R Shift Shft 55 KEY_KP_MULTIPLY * 56 KEY_ALT_L Alt 57 KEY_SPACE Space Spc 58 KEY_CAPS_LOCK Multi Caps 59 KEY_F1 F1 60 KEY_F2 F2 61 KEY_F3 F3 62 KEY_F4 F4 63 KEY_F5 F5 64 KEY_F6 F6 65 KEY_F7 F7 66 KEY_F8 F8 67 KEY_F9 F9 68 KEY_F10 F10 69 KEY_NUM_LOCK Num 70 KEY_SCROLL_LOCK Scrl 71 KEY_KP_HOME 7 72 KEY_KP_UP 8 73 KEY_KP_PRIOR 9 74 KEY_KP_SUBTRACT - 75 KEY_KP_LEFT 4 76 KEY_KP_BEGIN 5 77 KEY_KP_RIGHT 6 78 KEY_KP_ADD + 79 KEY_KP_END 1 80 KEY_KP_DOWN 2 81 KEY_KP_PAGE_DOWN 3 82 KEY_KP_INSERT 0 83 KEY_KP_DELETE . 84 KEY_ISO_LEVEL3_SHIFT AltGr 86 KEY_LESS < 87 KEY_L1 F11 88 KEY_L2 F12 90 KEY_KATAKANA KATAKANA 91 KEY_HIRAGANA HIRAGANA 92 KEY_HENKAN_MODE HENKAN_MODE 93 KEY_HIRAGANA_KATAKANA HIRAGANA_KATAKANA 94 KEY_MUHENKAN MUHENKAN 96 KEY_KP_ENTER ⏎ 97 KEY_CONTROL_R Ctrl 98 KEY_KP_DIVIDE / 99 KEY_PRINT Print Prt 100 KEY_ALT_R Alt 101 KEY_LINEFEED Lf Lf 102 KEY_HOME Home Hm 103 KEY_UP ↑ 104 KEY_PRIOR PgUp 105 KEY_LEFT ← 106 KEY_RIGHT → 107 KEY_END End 108 KEY_DOWN ↓ 109 KEY_PAGE_DOWN PgDn 110 KEY_INSERT Ins Ins 111 KEY_DELETE Del Del 113 KEY_AUDIOMUTE Mute Mute 114 KEY_AUDIOLOWERVOLUME Vol- V- 115 KEY_AUDIORAISEVOLUME Vol+ V+ 116 KEY_POWEROFF Off Off 117 KEY_KP_EQUAL = 118 KEY_PLUSMINUS +/- 119 KEY_PAUSE Pause Ps 121 KEY_KP_DECIMAL . 122 KEY_HANGUL HANGUL 123 KEY_HANGUL_HANJA HANGUL_HANJA 125 KEY_SUPER_L Super Spr 126 KEY_SUPER_R Super Spr 127 KEY_MENU Menu Men 128 KEY_CANCEL Cancel Can 129 KEY_REDO Redo Red 130 KEY_SUNPROPS Sunprops 131 KEY_UNDO Undo Und 132 KEY_SUNFRONT Sunfront 133 KEY_COPY Copy Cp 134 KEY_SUNOPEN SunOpen 135 KEY_PASTE Paste 136 KEY_FIND Find 137 KEY_CUT Cut Cut 138 KEY_HELP Help 139 KEY_MENUKB MenuKb MenuKb 140 KEY_CALCULATOR Calc 142 KEY_SLEEP Sleep 143 KEY_WAKEUP Fn 144 KEY_EXPLORER Explorer 145 KEY_SEND Send 147 KEY_XFER Xfer 148 KEY_LAUNCH1 Launch1 149 KEY_LAUNCH2 Launch2 150 KEY_WWW www 151 KEY_DOS Dos 152 KEY_SCREENSAVER Screensaver 154 KEY_ROTATEWINDOWS RotateWin 155 KEY_MAIL Mail 156 KEY_FAVORITES Fav 157 KEY_MYCOMPUTER MyComputer 158 KEY_BACK ⇐ 159 KEY_FORWARD ⇒ 161 KEY_EJECT Eject 162 KEY_EJECT Eject 163 KEY_AUDIONEXT Next 164 KEY_AUDIOPLAY Play 165 KEY_AUDIOPREV Prev 166 KEY_AUDIOSTOP Stop 167 KEY_AUDIORECORD Record 168 KEY_AUDIOREWIND Rewind 169 KEY_PHONE Phone 171 KEY_TOOLS Tools 172 KEY_HOMEPAGE HomePage 173 KEY_RELOAD Reload 174 KEY_CLOSE Close 177 KEY_SCROLLUP ScrollUp 178 KEY_SCROLLDOWN ScrollDn 179 KEY_PARENLEFT ( 180 KEY_PARENRIGHT ) 181 KEY_NEW New 182 KEY_REDO Redo Red 195 KEY_MODE_SWITCH Mode 196 KEY_NOSYMBOL - 197 KEY_NOSYMBOL - 198 KEY_NOSYMBOL - 199 KEY_NOSYMBOL - 200 KEY_AUDIOPLAY Play 201 KEY_AUDIOPAUSE Pause 202 KEY_LAUNCH3 Launch3 203 KEY_LAUNCH4 Launch4 205 KEY_SUSPEND Suspend 206 KEY_CLOSE Close 207 KEY_AUDIOPLAY Play 208 KEY_FORWARD Forward 210 KEY_PRINT Print Prt 212 KEY_WEBCAM WebCam 215 KEY_MAIL Mail 217 KEY_SEARCH Search 219 KEY_FINANCE Finance 221 KEY_SHOP Shop 223 KEY_CANCEL Cancel Can 224 KEY_MONBRIGHTNESSDOWN BrightnessDown 225 KEY_MONBRIGHTNESSUP BrightnessUp 226 KEY_AUDIOMEDIA AudioMedia 227 KEY_DISPLAY Display 228 KEY_KBDLIGHTONOFF LightOnOff 229 KEY_KBDBRIGHTNESSDOWN BrightnessDown 230 KEY_KBDBRIGHTNESSUP BrightnessUp 231 KEY_SEND Send 232 KEY_REPLY Reply 233 KEY_MAILFORWARD MailForward 234 KEY_SAVE Save 235 KEY_DOCUMENTS Docs 236 KEY_BATTERY Battery 237 KEY_BLUETOOTH Bluetooth 238 KEY_WLAN Lan NOKEY_000 KEY_MULTI_KEY Multi Mul key-mon-1.17/src/keymon/options.py0000750006766500116100000003423412130344127020676 0ustar scottkirkwoodeng00000000000000#!/usr/bin/python # # Copyright 2010 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Options Class for save, restoring and getting parameters from the command line. This provides a class which handles both saving options to disk and gathering options from the command line. It behaves a little like optparse in that you can get or set the attributes by name. It uses ConfigParser to save the variables to disk in ini format. """ __author__ = 'Scott Kirkwood (scott+keymon@forusers.com)' import ConfigParser import gettext import logging import optparse import os import sys LOG = logging.getLogger('options') gettext.install('key-mon', 'locale') class OptionException(Exception): pass class OptionItem(object): """Handles on option. It know both about optparse options and ConfigParser options. By setting opt_short, opt_long to None you won't create an optparse option. By setting ini_group, ini_name to None you won't create a ConfigParser option. """ def __init__(self, dest, _type, default, name, help, opt_group=None, opt_short=None, opt_long=None, ini_group=None, ini_name=None): """Create an option Args: dest: a unique name for this variable, used internally. _type: The data type. default: The default value if none given. name: the translated name. _help: Help text to show. opt_group: Optional option group opt_short: the short name of the option opt_long: the long name for the option ini_group: optional name of the group in the ini file. ini_name: optional name of the name in the ini file """ self._dirty = False self._value = None self._temp_value = None self._dest = dest self._type = _type self._default = default self._name = name self._help = help self._opt_group = opt_group self._opt_short = opt_short if self._opt_short and not self._opt_short.startswith('-'): raise OptionException('Invalid short option %s' % self._opt_short) self._opt_long = opt_long if self._opt_long and not self._opt_long.startswith('--'): raise OptionException('Invalid long option %r' % self._opt_long) self._ini_group = ini_group self._ini_name = ini_name if self._type not in ('int', 'float', 'bool', 'str'): raise OptionException('Unsupported type: %s' % self._type) self._set_value(default) def add_to_parser(self, parser): if not self._opt_short and not self._opt_long: return if self._type == 'bool': self._add_bool_to_parser(parser) return args = [] if self._opt_short: args.append(self._opt_short) if self._opt_long: args.append(self._opt_long) parser.add_option(dest=self._dest, type=self._type, default=self._default, help=self._help, *args) def _add_bool_to_parser(self, parser): """Booleans need special handling.""" args = [] if self._opt_short: args.append(self._opt_short) if self._opt_long: args.append(self._opt_long) parser.add_option(action='store_true', default=self._default, dest=self._dest, help=self._help, *args) if self._ini_group: # Only need the --no version if it could be saved to ini file. parser.add_option('--no' + self._opt_long.lstrip('-'), action='store_false', dest=self._dest, help=_('Opposite of %s') % self._opt_long) def set_from_optparse(self, opts, args): """Try and set an option from optparse. Args: opts: options as returned from parse_args() args: arguments as returned bys sys.args. """ if not self._opt_short and not self._opt_long: return # Was this option actually passed on the command line? found = False if args: for arg in args: if self._type == 'bool' and arg.startswith('--no'): arg = '--' + arg[4:] # Remove the --x=123, if any arg = arg.split('=')[0] if arg == self._opt_short or arg == self._opt_long: found = True break if hasattr(opts, self._dest): opt_val = getattr(opts, self._dest) if not self._ini_name: # For commands like --version which don't have stored values self._set_value(opt_val) if found: self._set_temp_value(opt_val) def reset_to_default(self): """Reset to the default value.""" self._set_value(self._default) self._set_temp_value(None) def get_value(self): """Return the value.""" if self._temp_value is not None: return self._temp_value return self._value def _set_attr_value(self, attr, val): """Set the value via attribute name. Args: attr: attribute name ('_value', or '_temp_value') val: value to set """ old_val = getattr(self, attr) if val is None: setattr(self, attr, val) elif self._type == 'int': setattr(self, attr, int(val)) elif self._type == 'float': setattr(self, attr, float(val)) elif self._type == 'bool': if isinstance(val, basestring): if val.lower() in ('false', 'off', 'no', '0'): setattr(self, attr, False) elif val.lower() in ('true', 'on', 'yes', '1'): setattr(self, attr, True) else: raise OptionException('Unable to convert %s to bool' % val) else: setattr(self, attr, bool(val)) else: setattr(self, attr, val) self._dirty = old_val != getattr(self, attr) def _set_value(self, val): self._set_attr_value('_value', val) self._set_attr_value('_temp_value', None) def _set_temp_value(self, val): self._set_attr_value('_temp_value', val) value = property(get_value, _set_value, doc="Value") @property def dest(self): """Destination variable name.""" return self._dest @property def name(self): """Localized name of the option.""" return self._name @property def help(self): """Long description of the option.""" return self._help @property def type(self): """String name of the type.""" return self._type @property def opt_group(self): """Option group, if any.""" return self._opt_group @property def opt_short(self): """Short option property (ex. '-v').""" return self._opt_short @property def opt_long(self): """Long option property (ex. '--verbose').""" return self._opt_long @property def ini_group(self): """Name of the ini group or None.""" return self._ini_group @property def ini_name(self): """Name in the ini, or None.""" return self._ini_name @property def ini_value(self): """Value to store in the ini, always a string.""" if self._value is None: return None if self._type == 'bool': if self._value is True: return '1' else: return '0' else: return str(self._value) class Options(object): """Store the options in memory, also saves to dist and creates opt_parser.""" def __init__(self): self._options = {} self._ini_filename = None self._opt_group = None self._opt_group_desc = {} self._options_order = [] def __getattr__(self, name): if name not in self.__dict__['_options']: raise AttributeError('Invalid attribute name: %r' % name) return self._options[name].value def __setattr__(self, name, value): if name == '_options' or name not in self.__dict__['_options']: object.__setattr__(self, name, value) else: LOG.info('Setting %r = %r', name, value) self.__dict__['_options'][name].value = value def add_option_group(self, group, desc): self._opt_group = group self._opt_group_desc[group] = desc def add_option(self, dest, type='str', default=None, name=None, help=None, opt_short=None, opt_long=None, ini_group=None, ini_name=None): """Create an option Args: dest: a unique name for this variable, used internally. type: The data type. default: The default value if none given. name: the translated name. help: Help text to show. opt_group: the name of the option group or None opt_short: the short name of the option opt_long: the long name for the option ini_group: the name of the group in the ini file. ini_name: the name of the name in the ini file """ if dest in self._options: raise OptionException('Options %s already added' % dest) self._options_order.append(dest) self._options[dest] = OptionItem(dest, type, default, name, help, opt_group=self._opt_group, opt_short=opt_short, opt_long=opt_long, ini_group=ini_group, ini_name=ini_name) def parse_args(self, desc, args=None): """Add the options to the optparse instance and parse command line Args: desc: Description to use for the program. args: Args for testing or sys.args[1:] otherwise """ parser = optparse.OptionParser(desc) for dest in self._options_order: opt = self._options[dest] opt.add_to_parser(parser) self._opt_ret, self._other_args = parser.parse_args(args) for opt in self._options.values(): opt.set_from_optparse(self._opt_ret, args) def parse_ini(self, fp): """Parser an ini file from fp, which is file-like class.""" config = ConfigParser.SafeConfigParser() config.readfp(fp) checker = {} for opt in self._options.values(): if opt.ini_group: checker[opt.ini_group + '-' + opt.ini_name] = True if (config.has_section(opt.ini_group) and config.has_option(opt.ini_group, opt.ini_name)): opt.value = config.get(opt.ini_group, opt.ini_name) LOG.info('From ini getting %s.%s = %s', opt.ini_group, opt.ini_name, opt.value) for section in config.sections(): for name, value in config.items(section): combined_name = section + '-' + name if not combined_name in checker: LOG.info('Unknown option %r in section [%s]', name, section) # we no longer throw an error to be backward compatible def write_ini(self, fp): """Parser an ini file from fp, which is file-like class.""" config = ConfigParser.SafeConfigParser() for opt in self._options.values(): if not opt.ini_group: continue if not config.has_section(opt.ini_group): config.add_section(opt.ini_group) if opt.ini_value is not None: config.set(opt.ini_group, opt.ini_name, opt.ini_value) config.write(fp) def read_ini_file(self, fname): self._ini_filename = os.path.expanduser(fname) LOG.info('Reading from %r', self._ini_filename) if os.path.exists(self._ini_filename) and os.path.isfile(self._ini_filename): fi = open(self._ini_filename) self.parse_ini(fi) fi.close() else: LOG.info('%r does not exist', self._ini_filename) def save(self): self._write_ini_file(self._ini_filename) def _make_dirs(self, fname): if not os.path.exists(fname): dirname = os.path.dirname(fname) if not os.path.exists(dirname): LOG.info('Creating directory %r', dirname) os.makedirs(dirname) def _write_ini_file(self, fname): self._make_dirs(fname) LOG.info('Writing config file %r', fname) fo = open(fname, 'w') self.write_ini(fo) fo.close() def reset_to_defaults(self): """Reset ini file to defaults.""" for opt in self._options.values(): if not opt.ini_group: continue opt.reset_to_default() if __name__ == '__main__': o = Options() o.add_option(opt_short='-l', opt_long='--larger', dest='larger', default=False, type='bool', help='Make the dialog 25% larger than normal.') o.add_option(opt_short='-m', opt_long='--meta', dest='meta', type='bool', ini_group='buttons', ini_name='meta', default=False, help='Show the meta (windows) key.') o.add_option(opt_long='--scale', dest='scale', type='float', default=1.0, ini_group='ui', ini_name='scale', help='Scale the dialog. ex. 2.0 is 2 times larger, 0.5 is ' 'half the size. Defaults to %default') o.add_option(opt_long='--kbdfile', dest='kbd_file', ini_group='devices', ini_name='map', default='us.kbd', help='Use this kbd filename instead running xmodmap.') o.add_option(opt_short='-v', opt_long='--version', dest='version', type='bool', help='Show version information and exit.') o.add_option(opt_short='-t', opt_long='--theme', dest='theme', type='str', ini_group='ui', ini_name='theme', help='The theme to use when drawing status images (ex. "-t apple").') o.add_option(opt_long='--list-themes', dest='list_themes', type='bool', help='List available themes') o.add_option(opt_long='--old-keys', dest='old_keys', type='int', ini_group='buttons', ini_name='old-keys', help='How many historical keypresses to show (defaults to %default)', default=0) o.add_option(opt_short=None, opt_long=None, type='int', dest='x_pos', default=-1, help='Last X Position', ini_group='position', ini_name='x') o.add_option_group('Developer Options', 'Don\'t use') o.add_option(opt_short='-d', opt_long='--debug', dest='debug', type='bool', help='Output debugging information.') lines = [] lines.append('[ui]') lines.append('scale = 1.0') lines.append('theme = classic') lines.append('[buttons]') lines.append('meta = 0') lines.append('old-keys = 0') lines.append('[devices]') lines.append('map = us.kbd') lines.append('[position]') lines.append('x = -1') import StringIO io = StringIO.StringIO('\n'.join(lines)) o.parse_ini(io) o.parse_args('%prog [options]', sys.argv) io = StringIO.StringIO() o.write_ini(io) print io.getvalue() key-mon-1.17/src/keymon/shaped_window.py0000750006766500116100000000607212130344127022035 0ustar scottkirkwoodeng00000000000000#!/usr/bin/python # # Copyright 2010 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Create a shaped window to show mouse events. Thanks to mathias.gumz for the original code. """ import gobject import gtk import lazy_pixbuf_creator class ShapedWindow(gtk.Window): """Create a window shaped as fname.""" def __init__(self, fname, scale=1.0, timeout=0.2): gtk.Window.__init__(self) self.connect('size-allocate', self._on_size_allocate) self.set_decorated(False) self.set_keep_above(True) self.set_accept_focus(False) self.scale = scale self.shown = False self.timeout = timeout self.timeout_timer = None self.name_fnames = { 'mouse' : [fname], } self.pixbufs = lazy_pixbuf_creator.LazyPixbufCreator(self.name_fnames, self.scale) self.pixbuf = self.pixbufs.get('mouse') self.resize(self.pixbuf.get_width(), self.pixbuf.get_height()) # a pixmap widget to contain the pixmap self.image = gtk.Image() bitmap, self.mask = self.pixbuf.render_pixmap_and_mask() self.image.set_from_pixmap(bitmap, self.mask) self.image.show() self.add(self.image) def _on_size_allocate(self, win, unused_allocation): """Called when first allocated.""" # Set the window shape win.shape_combine_mask(self.mask, 0, 0) win.set_property('skip-taskbar-hint', True) if not win.is_composited(): print 'Unable to fade the window' else: win.set_opacity(0.5) def center_on_cursor(self, x=None, y=None): if x is None or y is None: root = gtk.gdk.screen_get_default().get_root_window() x, y, _ = root.get_pointer() w, h = self.get_size() new_x, new_y = x - w/2, y - h/2 pos = self.get_position() if pos[0] != new_x or pos[1] != new_y: self.move(new_x, new_y) self.show() def show(self): """Show this mouse indicator and ignore awaiting fade away request.""" if self.timeout_timer: # There is a fade away request, ignore it gobject.source_remove(self.timeout_timer) self.timeout_timer = None # This method only is called when mouse is pressed, so there will be a # release and fade_away call, no need to set up another timer. super(ShapedWindow, self).show() def maybe_show(self): if self.shown: return self.shown = True self.show() def fade_away(self): """Make the window fade in a little bit.""" # TODO this isn't doing any fading out self.shown = True self.timeout_timer = gobject.timeout_add(int(self.timeout * 1000), self.hide) key-mon-1.17/src/keymon/__init__.py0000750006766500116100000000001412130344127020727 0ustar scottkirkwoodeng00000000000000"""Empty""" key-mon-1.17/src/keymon/tr.kbd0000640006766500116100000001107212130344127017731 0ustar scottkirkwoodeng00000000000000# This is a space separated file with UTF-8 encoding # Short name is optional, will default to the medium-name # Scancode Map-Name Medium-Name Short-Name 1 KEY_ESCAPE Esc 2 KEY_1 1 3 KEY_2 2 4 KEY_3 3 5 KEY_4 4 6 KEY_5 5 7 KEY_6 6 8 KEY_7 7 9 KEY_8 8 10 KEY_9 9 11 KEY_0 0 12 KEY_ASTERISK * 13 KEY_MINUS - 14 KEY_BACKSPACE Back ⇽ 15 KEY_TAB Tab 16 KEY_Q Q 17 KEY_W W 18 KEY_E E 19 KEY_R R 20 KEY_T T 21 KEY_Y Y 22 KEY_U U 23 KEY_IDOTLESS I 24 KEY_O O 25 KEY_P P 26 KEY_GBREVE Ğ 27 KEY_UDIAERESIS Ü 28 KEY_RETURN Return ⏎ 29 KEY_CONTROL_L Ctrl Ctl 30 KEY_A A 31 KEY_S S 32 KEY_D D 33 KEY_F F 34 KEY_G G 35 KEY_H H 36 KEY_J J 37 KEY_K K 38 KEY_L L 39 KEY_SCEDILLA Ş 40 KEY_I İ 41 KEY_QUOTEDBL " 42 KEY_SHIFT_L Shift Shft 43 KEY_COMMA , 44 KEY_Z Z 45 KEY_X X 46 KEY_C C 47 KEY_V V 48 KEY_B B 49 KEY_N N 50 KEY_M M 51 KEY_ODIAERESIS Ö 52 KEY_CCEDILLA Ç 53 KEY_PERIOD . 54 KEY_SHIFT_R Shift Shft 55 KEY_KP_MULTIPLY * 56 KEY_ALT_L Alt 57 KEY_SPACE Space Spc 58 KEY_CAPS_LOCK CAPS_LOCK 59 KEY_F1 F1 60 KEY_F2 F2 61 KEY_F3 F3 62 KEY_F4 F4 63 KEY_F5 F5 64 KEY_F6 F6 65 KEY_F7 F7 66 KEY_F8 F8 67 KEY_F9 F9 68 KEY_F10 F10 69 KEY_NUM_LOCK Num 70 KEY_SCROLL_LOCK Scrl 71 KEY_KP_HOME 7 72 KEY_KP_UP 8 73 KEY_KP_PRIOR 9 74 KEY_KP_SUBTRACT - 75 KEY_KP_LEFT 4 76 KEY_KP_BEGIN 5 77 KEY_KP_RIGHT 6 78 KEY_KP_ADD + 79 KEY_KP_END 1 80 KEY_KP_DOWN 2 81 KEY_KP_NEXT 3 82 KEY_KP_INSERT 0 83 KEY_KP_DELETE . 84 KEY_ISO_LEVEL3_SHIFT Alt 86 KEY_LESS < 87 KEY_F11 F11 88 KEY_F12 F12 90 KEY_KATAKANA KATAKANA 91 KEY_HIRAGANA HIRAGANA 92 KEY_HENKAN_MODE HENKAN_MODE 93 KEY_HIRAGANA_KATAKANA HIRAGANA_KATAKANA 94 KEY_MUHENKAN MUHENKAN 96 KEY_KP_ENTER ⏎ 97 KEY_CONTROL_R Ctrl 98 KEY_KP_DIVIDE / 99 KEY_PRINT Print Prt 100 KEY_ISO_LEVEL3_SHIFT Alt 101 KEY_LINEFEED Lf Lf 102 KEY_HOME Home Hm 103 KEY_UP ↑ 104 KEY_PRIOR PgUp PgU 105 KEY_LEFT ← 106 KEY_RIGHT → 107 KEY_END End 108 KEY_DOWN ↓ 109 KEY_NEXT PgDn PgD 110 KEY_INSERT Ins Ins 111 KEY_DELETE Del Del 113 KEY_AUDIOMUTE Mute Mute 114 KEY_AUDIOLOWERVOLUME Vol- V- 115 KEY_AUDIORAISEVOLUME Vol+ V+ 116 KEY_POWEROFF Off Off 117 KEY_KP_EQUAL = 118 KEY_PLUSMINUS +/- 119 KEY_PAUSE Pause Ps 120 KEY_LAUNCHA XF86LAUNCHA 121 KEY_KP_DECIMAL . 122 KEY_HANGUL HANGUL 123 KEY_HANGUL_HANJA HANGUL_HANJA 125 KEY_SUPER_L Super Spr 126 KEY_SUPER_R SUPER_R 127 KEY_MENU Menu Men 128 KEY_CANCEL Cancel Can 129 KEY_REDO Redo Red 130 KEY_SUNPROPS Sunprops 131 KEY_UNDO Undo Und 132 KEY_SUNFRONT Sunfront 133 KEY_COPY Copy Cp 134 KEY_SUNOPEN SunOpen 135 KEY_PASTE Paste 136 KEY_FIND Find 137 KEY_CUT Cut Cut 138 KEY_HELP Help 139 KEY_MENUKB MenuKb MenuKb 140 KEY_CALCULATOR Calc 142 KEY_SLEEP Sleep 143 KEY_WAKEUP Wake 144 KEY_EXPLORER Explorer 145 KEY_SEND Send 147 KEY_XFER Xfer 148 KEY_LAUNCH1 Launch1 149 KEY_LAUNCH2 Launch2 150 KEY_WWW www 151 KEY_DOS Dos 152 KEY_SCREENSAVER Screensaver 154 KEY_ROTATEWINDOWS RotateWin 155 KEY_MAIL Mail 156 KEY_FAVORITES Fav 157 KEY_MYCOMPUTER MyComputer 158 KEY_BACK ⇐ 159 KEY_FORWARD ⇒ 161 KEY_EJECT Eject 162 KEY_EJECT Eject 163 KEY_AUDIONEXT Next 164 KEY_AUDIOPLAY Play 165 KEY_AUDIOPREV Prev 166 KEY_AUDIOSTOP Stop 167 KEY_AUDIORECORD Record 168 KEY_AUDIOREWIND Rewind 169 KEY_PHONE Phone 171 KEY_TOOLS Tools 172 KEY_HOMEPAGE HomePage 173 KEY_RELOAD Reload 174 KEY_CLOSE Close 177 KEY_SCROLLUP ScrollUp 178 KEY_SCROLLDOWN ScrollDn 179 KEY_PARENLEFT ( 180 KEY_PARENRIGHT ) 181 KEY_NEW New 182 KEY_REDO Redo Red 183 KEY_TOOLS Tools 184 KEY_LAUNCH5 XF86LAUNCH5 185 KEY_LAUNCH6 XF86LAUNCH6 186 KEY_LAUNCH7 XF86LAUNCH7 187 KEY_LAUNCH8 XF86LAUNCH8 188 KEY_LAUNCH9 XF86LAUNCH9 191 KEY_TOUCHPADTOGGLE XF86TOUCHPADTOGGLE 192 KEY_TOUCHPADON XF86TOUCHPADON 193 KEY_TOUCHPADOFF XF86TOUCHPADOFF 195 KEY_MODE_SWITCH Mode 196 KEY_NOSYMBOL - 197 KEY_NOSYMBOL - 198 KEY_NOSYMBOL - 199 KEY_NOSYMBOL - 200 KEY_AUDIOPLAY Play 201 KEY_AUDIOPAUSE Pause 202 KEY_LAUNCH3 Launch3 203 KEY_LAUNCH4 Launch4 204 KEY_LAUNCHB XF86LAUNCHB 205 KEY_SUSPEND Suspend 206 KEY_CLOSE Close 207 KEY_AUDIOPLAY Play 208 KEY_AUDIOFORWARD XF86AUDIOFORWARD 210 KEY_PRINT Print Prt 212 KEY_WEBCAM WebCam 215 KEY_MAIL Mail 216 KEY_MESSENGER XF86MESSENGER 217 KEY_SEARCH Search 218 KEY_GO XF86GO 219 KEY_FINANCE Finance 220 KEY_GAME XF86GAME 221 KEY_SHOP Shop 223 KEY_CANCEL Cancel Can 224 KEY_MONBRIGHTNESSDOWN BrightnessDown 225 KEY_MONBRIGHTNESSUP BrightnessUp 226 KEY_AUDIOMEDIA AudioMedia 227 KEY_DISPLAY Display 228 KEY_KBDLIGHTONOFF LightOnOff 229 KEY_KBDBRIGHTNESSDOWN BrightnessDown 230 KEY_KBDBRIGHTNESSUP BrightnessUp 231 KEY_SEND Send 232 KEY_REPLY Reply 233 KEY_MAILFORWARD MailForward 234 KEY_SAVE Save 235 KEY_DOCUMENTS Docs 236 KEY_BATTERY Battery 237 KEY_BLUETOOTH Bluetooth 238 KEY_WLAN Lan NOKEY_000 KEY_MULTI_KEY Multi Mul key-mon-1.17/src/keymon/mod_mapper.py0000750006766500116100000002604512130344127021327 0ustar scottkirkwoodeng00000000000000#!/usr/bin/python # # Copyright 2010 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Run mod map and convert to something I can use.""" __author__ = 'scott@forusers.com (scottkirkwood)' import codecs import logging import os import re import subprocess MEDIUM_NAME = { 'ESCAPE': 'Esc', 'PLUS': '+', 'MINUS': '-', 'EQUAL': '=', 'BACKSPACE': 'Back', 'TAB': 'Tab', 'BRACKETLEFT': '[', 'BRACKETRIGHT': ']', 'BRACELEFT': '(', 'BRACERIGHT': ')', 'DEAD_ACUTE': u'\u00B4', 'ACUTE': u'\u00B4', 'QUESTIONDOWN': u'\u00BF', 'WAKEUP': 'Wake', 'BAR': '|', 'TILDE': '~', 'NTILDE': '~', 'RETURN': 'Return', 'CONTROL_L': 'Ctrl', 'SEMICOLON': ';', 'APOSTROPHE': '\'', 'GRAVE': '`', 'SHIFT_L': 'Shift', 'BACKSLASH': '\\', 'COMMA': ',', 'PERIOD': '.', 'SLASH': '/', 'SHIFT_R': 'Shift', 'KP_MULTIPLY': '*', 'ALT_L': 'Alt', 'ALT_R': 'Alt', 'SPACE': 'Space', 'MULTI_KEY': 'Multi', 'NUM_LOCK': 'Num', 'SCROLL_LOCK': 'Scrl', 'KP_HOME': '7', 'KP_UP': '8', 'KP_PRIOR': '9', 'KP_SUBTRACT': '-', 'KP_LEFT': '4', 'KP_BEGIN': '5', 'KP_RIGHT': '6', 'KP_ADD': '+', 'KP_END': '1', 'KP_DOWN': '2', 'KP_PAGE_DOWN': '3', 'KP_NEXT': '3', 'KP_INSERT': '0', 'KP_DELETE': '.', 'ISO_LEVEL3_SHIFT': 'Alt', # Right Alt 'LESS': '<', 'KP_ENTER': u'\u23CE', 'CONTROL_R': 'Ctrl', 'KP_DIVIDE': '/', 'PRINT': 'Print', 'LINEFEED': 'Lf', 'HOME': 'Home', 'UP': u'\u2191', 'PRIOR': 'PgUp', 'LEFT': u'\u2190', 'RIGHT': u'\u2192', 'END': 'End', 'DOWN': u'\u2193', 'NEXT': 'PgDn', 'INSERT': 'Ins', 'DELETE': 'Del', 'XF86AUDIOMUTE': 'Mute', 'XF86AUDIOLOWERVOLUME': 'Vol-', 'XF86AUDIORAISEVOLUME': 'Vol+', 'XF86POWEROFF': 'Off', 'KP_EQUAL': '=', 'PLUSMINUS': '+/-', 'PAUSE': 'Pause', 'KP_DECIMAL': '.', 'SUPER_L': 'Super', 'MENU': 'Menu', 'CANCEL': 'Cancel', 'REDO': 'Redo', 'SUNPROPS': 'Sunprops', 'UNDO': 'Undo', 'SUNFRONT': 'Sunfront', 'XF86COPY': 'Copy', 'SUNOPEN': 'SunOpen', 'XF86PASTE': 'Paste', 'FIND': 'Find', 'XF86CUT': 'Cut', 'HELP': 'Help', 'XF86MENUKB': 'MenuKb', 'XF86CALCULATOR': 'Calc', 'XF86SLEEP': 'Sleep', 'XF86WAKEUP': 'Wake', 'XF86EXPLORER': 'Explorer', 'XF86SEND': 'Send', 'XF86XFER': 'Xfer', 'XF86LAUNCH1': 'Launch1', 'XF86LAUNCH2': 'Launch2', 'XF86WWW': 'www', 'XF86DOS': 'Dos', 'XF86SCREENSAVER': 'Screensaver', 'XF86ROTATEWINDOWS': 'RotateWin', 'XF86MAIL': 'Mail', 'XF86FAVORITES': 'Fav', 'XF86MYCOMPUTER': 'MyComputer', 'XF86BACK': u'\u21d0', 'XF86FORWARD': u'\u21d2', 'XF86EJECT': 'Eject', 'XF86AUDIONEXT': 'Next', 'XF86AUDIOPLAY': 'Play', 'XF86AUDIOPREV': 'Prev', 'XF86AUDIOSTOP': 'Stop', 'XF86AUDIORECORD': 'Record', 'XF86AUDIOREWIND': 'Rewind', 'XF86PHONE': 'Phone', 'XF86TOOLS': 'Tools', 'XF86HOMEPAGE': 'HomePage', 'XF86RELOAD': 'Reload', 'XF86CLOSE': 'Close', 'XF86SCROLLUP': 'ScrollUp', 'XF86SCROLLDOWN': 'ScrollDn', 'PARENLEFT': '(', 'PARENRIGHT': ')', 'XF86NEW': 'New', 'MODE_SWITCH': 'Mode', 'NOSYMBOL': '-', 'XF86AUDIOPAUSE': 'Pause', 'XF86LAUNCH3': 'Launch3', 'XF86LAUNCH4': 'Launch4', 'XF86SUSPEND': 'Suspend', 'XF86WEBCAM': 'WebCam', 'XF86SEARCH': 'Search', 'XF86FINANCE': 'Finance', 'XF86SHOP': 'Shop', 'XF86MONBRIGHTNESSDOWN': 'BrightnessDown', 'XF86MONBRIGHTNESSUP': 'BrightnessUp', 'XF86AUDIOMEDIA': 'AudioMedia', 'XF86DISPLAY': 'Display', 'XF86KBDLIGHTONOFF': 'LightOnOff', 'XF86KBDBRIGHTNESSDOWN': 'BrightnessDown', 'XF86KBDBRIGHTNESSUP': 'BrightnessUp', 'XF86REPLY': 'Reply', 'XF86MAILFORWARD': 'MailForward', 'XF86SAVE': 'Save', 'XF86DOCUMENTS': 'Docs', 'XF86BATTERY': 'Battery', 'XF86BLUETOOTH': 'Bluetooth', 'XF86WLAN': 'Lan', } SHORT_NAME = { 'BACKSPACE': u'\u21fd', 'RETURN': u'\u23CE', 'CONTROL_L': 'Ctl', 'SHIFT_L': 'Shft', 'SHIFT_R': 'Shft', 'SPACE': 'Spc', 'PRINT': 'Prt', 'LINEFEED': 'Lf', 'HOME': 'Hm', 'INSERT': 'Ins', 'DELETE': 'Del', 'XF86AUDIOMUTE': 'Mute', 'XF86AUDIOLOWERVOLUME': 'V-', 'XF86AUDIORAISEVOLUME': 'V+', 'XF86POWEROFF': 'Off', 'PRIOR': 'PgU', 'NEXT': 'PgD', 'PAUSE': 'Ps', 'SUPER_L': 'Spr', 'MULTI_KEY': 'Mul', 'MENU': 'Men', 'CANCEL': 'Can', 'REDO': 'Red', 'UNDO': 'Und', 'XF86COPY': 'Cp', 'XF86CUT': 'Cut', 'XF86MENUKB': 'MenuKb', } class ModMapper(object): """Converts Mod Map codes into names and strings.""" def __init__(self): self.map = {} self.alt_map = {} self.name_to_code = {} def done(self): """done setup, now create alt_map and name_to_code.""" for key in self.map: vals = self.map[key] code_name = vals[0] self.alt_map[code_name] = vals self.name_to_code[code_name] = key def set_map(self, code, vals): """Set one code.""" self.map[code] = vals def get_and_check(self, scancode, name): """Get the scan code, or get from name.""" if scancode in self.map: vals = self.map[scancode] if vals[0] == name: return vals else: logging.debug('code %s != %s', vals[1], name) if name in self.alt_map: logging.info('Found key via alt lookup %s', name) return self.alt_map[name] logging.info('scancode: %r name:%r not found', scancode, name) return None, None, None def get_from_name(self, name): """Get the scancode from a name.""" if name in self.name_to_code: return self.name_to_code[name], self.alt_map[name] logging.info('Key %s not found', name) return None def __getitem__(self, key): try: return self.map[key] except: raise IndexError def __contains__(self, key): return key in self.map def __len__(self): return len(self.map) def parse_modmap(lines): """Parse a modmap file.""" re_range = re.compile(r'KeyCodes range from (\d+) to') lower_bound = 8 re_line = re.compile(r'^\s+(\d+)\s+0x[\dA-Fa-f]+\s+(.*)') re_remainder = re.compile(r'\((.+?)\)') ret = ModMapper() for line in lines.split('\n'): if not line: continue grps = re_range.search(line) if grps: lower_bound = int(grps.group(1)) grps = re_line.search(line) if grps: code = int(grps.group(1)) - lower_bound strlst = [] for grp in re_remainder.finditer(grps.group(2)): strlst.append(grp.group(1)) # We'll pick the first one alias = strlst[0].upper() my_keyname = 'KEY_' + alias my_keyname = my_keyname.replace('XF86', '') ret.set_map(code, (my_keyname, alias)) ret.done() return ret def read_kdb(fname): """Read the kdb file.""" logging.debug('Loading kbd file: %s' % fname) return parse_kdb( codecs.open( os.path.join(os.path.dirname(os.path.abspath(__file__)), fname), 'r', 'utf-8').read()) def parse_kdb(text): """Parse a kdb text file.""" re_line = re.compile(r'(\d+) (\S+) (\S+)\s?(\S*)') ret = ModMapper() for line in text.split('\n'): if not line: continue grps = re_line.search(line) if grps: ret.set_map(int(grps.group(1)), (grps.group(2), grps.group(3), grps.group(4))) ret.done() return ret def create_my_kdb(fname, codes): """Create a kdb file from scancodes.""" fout = codecs.open(fname, 'w', 'utf-8') fout.write('# This is a space separated file with UTF-8 encoding\n') fout.write('# Short name is optional, will default to the medium-name\n') fout.write('# Scancode Map-Name Medium-Name Short-Name\n') for code, (key, medium_name, short_name) in codes.map.items(): if short_name: fout.write('%d %s %s %s\n' % (code, key, medium_name, short_name)) else: fout.write('%d %s %s\n' % (code, key, medium_name)) print 'Output %r with %d entries' % (fname, len(codes)) fout.close() def mod_map_args(): """Return the arguments to pass to xmodmap.""" return ['xmodmap', '-display', ':0', '-pk'] def run_cmd(args): """Run the command and collect the output.""" return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0] def read_mod_map(): """Read a mod_map by runing xmodmap.""" logging.debug('Loading keymap from xmodmap...') xmodmap = parse_modmap(run_cmd(mod_map_args())) ret = ModMapper() for code in xmodmap.map: key = xmodmap[code][0] key_name = xmodmap[code][1] if key_name in MEDIUM_NAME: medium_name = MEDIUM_NAME[key_name] else: medium_name = key_name if key_name in SHORT_NAME: short_name = SHORT_NAME[key_name] else: short_name = None ret.set_map(code, (key, medium_name, short_name)) ret.done() return ret def safely_read_mod_map(fname, kbd_files): """Read the specified mod_map file or get the US version by default. Args: fname: name of kbd file to read kbd_files: list of full path of kbd files """ # Assigning a default kbdfile name using result of setxkbmap DEFAULT_KBD = None try: # TODO is -print the new -query ? for line in run_cmd(('setxkbmap', '-print')).split('\n'): if 'layout:' in line: DEFAULT_KBD = line.split(':')[1].strip() if 'variant:' in line: DEFAULT_KBD += '_' + line.split(':')[1].strip() if DEFAULT_KBD: logging.info('setxkbmap returns a keyboard layout_variant: %s' % DEFAULT_KBD) DEFAULT_KBD += '.kbd' except OSError: pass if not DEFAULT_KBD: DEFAULT_KBD = 'us.kbd' logging.info('Set default kbdfile to: %s' % DEFAULT_KBD) kbd_file = None kbd_default = None for kbd in kbd_files: if not kbd_file and fname and kbd.endswith(fname): kbd_file = kbd if not kbd_default and kbd.endswith(DEFAULT_KBD): kbd_default = kbd if fname and not kbd_file: logging.warning('Can not find kbd file: %s' % fname) if kbd_file: return read_kdb(kbd_file) ret = None if fname == 'xmodmap' or not kbd_default: try: ret = read_mod_map() except OSError: logging.error('unable execute xmodmap') if kbd_default: # Merge the defaults with modmap if fname == 'xmodmap': logging.debug('Merging with default kbd file: %s' % kbd_default) defaults = read_kdb(kbd_default) for keycode in defaults: if keycode not in ret: ret[keycode] = defaults[keycode] else: logging.debug('Using default kbd file: %s' % kbd_default) ret = read_kdb(kbd_default) else: logging.error('Can not find default kbd file') return ret def _run_test(): """Run some tests on the my.kbd file.""" filename = 'my.kdb' modmap = read_mod_map() create_my_kdb(filename, modmap) entries = read_kdb(filename) print 'Read %r with %d entires' % (filename, len(entries)) for ecode in modmap: if ecode not in entries: print 'Missing entry for code %s' % ecode if __name__ == '__main__': _run_test() key-mon-1.17/src/keymon/lazy_pixbuf_creator.py0000750006766500116100000001111312130344127023245 0ustar scottkirkwoodeng00000000000000#!/usr/bin/python # # Copyright 2010 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Create pixbuf on demand. This creates a gtk pixbuf in one of 2 manners: 1) Simple filename (probably supports most image formats) 2) A function which returns bytes to a file which can be read by pixbuf_new_from_file(). The name_fnames contains a list for key. Each element of the list will be composted with the previous element (overlayed on top of). Alpha transparencies from the new, overlayed, image are respected. """ __author__ = 'scott@forusers.com (Scott Kirkwood))' import pygtk pygtk.require('2.0') import gtk import logging import os import sys import re import tempfile import types class LazyPixbufCreator(object): """Class to create SVG images on the fly.""" def __init__(self, name_fnames, resize): """Initialize with empty. Args: name_fnames: List of names to filename list. """ self.pixbufs = {} self.resize = resize self.name_fnames = name_fnames def reset_all(self, names_fnames, resize): """Resets the name to filenames and size.""" self.pixbufs = {} self.name_fnames = names_fnames self.resize = resize def get(self, name): """Get the pixbuf with this name.""" if name not in self.pixbufs: name = self.create_pixbuf(name) return self.pixbufs[name] def create_pixbuf(self, name): """Creates the image. Args: name: name of the image we are to create. Returns: The name given or EMPTY if error. """ if name not in self.name_fnames: logging.error('Don\'t understand the name %r', name) return 'KEY_EMPTY' ops = self.name_fnames[name] img = None for operation in ops: if isinstance(operation, types.StringTypes): img = self._composite(img, self._read_from_file(operation)) else: image_bytes = operation() image_bytes = self._resize(image_bytes) img = self._composite(img, self._read_from_bytes(image_bytes)) self.pixbufs[name] = img return name def _composite(self, img, img2): """Combine/layer img2 on top of img. Args: img: original image (or None). img2: new image to add on top. Returns: updated image. """ if img: img2.composite(img, 0, 0, img.props.width, img.props.height, # x, y, w, h 0, 0, # offset x, y 1.0, 1.0, # scale x, y gtk.gdk.INTERP_HYPER, 255) # interpolation type, alpha return img return img2 def _read_from_file(self, fname): """Read in the file in from fname.""" logging.debug('Read file %s', fname) if self.resize == 1.0: return gtk.gdk.pixbuf_new_from_file(fname) fin = open(fname) image_bytes = self._resize(fin.read()) fin.close() return self._read_from_bytes(image_bytes) def _read_from_bytes(self, image_bytes): """Writes the bytes to a file and then reads the file.""" fout, fname = tempfile.mkstemp(prefix='keymon-', suffix='.svg') os.write(fout, image_bytes) os.close(fout) try: img = gtk.gdk.pixbuf_new_from_file(fname) except: logging.error('Unable to read %r: %s', fname, image_bytes) sys.exit(-1) try: os.unlink(fname) except OSError: pass return img def _resize(self, image_bytes): """Resize the image by manipulating the svg.""" if self.resize == 1.0: return image_bytes template = r'( image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-command/meta.svg0000640006766500116100000002756512130344127024276 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-command/mouse-follower.svg0000640006766500116100000000466312130344127026321 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-command/multi-char-template.svg0000640006766500116100000002560312130344127027215 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear-command/one-char-template.svg0000640006766500116100000002557712130344127026656 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear-command/scroll-up-mouse.svg0000640006766500116100000003121612130344127026402 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-command/whiteout-58.svg0000640006766500116100000002273112130344127025440 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-command/whiteout-48.svg0000640006766500116100000002273012130344127025436 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-command/one-char-numpad-template.svg0000640006766500116100000003020612130344127030121 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/clear-command/middle-mouse.svg0000640006766500116100000002460112130344127025720 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-command/mouse.svg0000640006766500116100000003715412130344127024473 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-command/scroll-lft-mouse.svg0000640006766500116100000002135712130344127026550 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-command/shift-small.svg0000640006766500116100000002606512130344127025565 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/clear-command/alt-small.svg0000640006766500116100000002557612130344127025236 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/clear-command/scroll-dn-mouse.svg0000640006766500116100000002775612130344127026375 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-command/shift.svg0000640006766500116100000002545312130344127024457 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/clear-command/alt.svg0000640006766500116100000002523412130344127024117 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/clear-command/mouse-indicator.svg0000640006766500116100000000475612130344127026447 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-command/two-line-wide.svg0000640006766500116100000002754312130344127026030 0ustar scottkirkwoodeng00000000000000 image/svg+xml TOP BOTTOM key-mon-1.17/src/keymon/themes/clear-command/right-mouse.svg0000640006766500116100000002460012130344127025576 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-command/scroll-rgt-mouse.svg0000640006766500116100000002135512130344127026555 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-command/ctrl.svg0000640006766500116100000002546512130344127024311 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/clear-command/multi-char-numpad-template-small.svg0000640006766500116100000003055112130344127031603 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/clear-command/altgr-small.svg0000640006766500116100000002562012130344127025555 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/clear-command/altgr.svg0000640006766500116100000002533012130344127024445 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/clear-command/one-char-template-small.svg0000640006766500116100000002561112130344127027751 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear-command/config0000640006766500116100000000025712130344127024004 0ustar scottkirkwoodeng00000000000000[theme] name = Clear-Comand description = A clean, modern theme authors = Nenad S. Lazich license = http://creativecommons.org/licenses/by-sa/3.0/us/ key-mon-1.17/src/keymon/themes/clear-command/whiteout-72.svg0000640006766500116100000002322512130344127025433 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-command/ctrl-small.svg0000640006766500116100000002560412130344127025412 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/clear-command/one-line-wide.svg0000640006766500116100000002621412130344127025772 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/apple/0000750006766500116100000000000012261424504021211 5ustar scottkirkwoodeng00000000000000key-mon-1.17/src/keymon/themes/apple/left-mouse.svg0000640006766500116100000002457612130344127024026 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/apple/meta.svg0000640006766500116100000002572112130344127022665 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/apple/mouse-follower.svg0000640006766500116100000000465412130344127024720 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/apple/multi-char-template.svg0000640006766500116100000002450212130344127025611 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/apple/one-char-template.svg0000640006766500116100000002447612130344127025252 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/apple/scroll-up-mouse.svg0000640006766500116100000003121612130344127025001 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/apple/whiteout-58.svg0000640006766500116100000002330612130344127024036 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/apple/whiteout-48.svg0000640006766500116100000002316012130344127024033 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/apple/one-char-numpad-template.svg0000640006766500116100000002602212130344127026521 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/apple/middle-mouse.svg0000640006766500116100000002460112130344127024317 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/apple/mouse.svg0000640006766500116100000004013012130344127023056 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/apple/scroll-lft-mouse.svg0000640006766500116100000002135712130344127025147 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/apple/shift-small.svg0000640006766500116100000002513212130344127024156 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/apple/alt-small.svg0000640006766500116100000002470312130344127023624 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/apple/scroll-dn-mouse.svg0000640006766500116100000002775612130344127024774 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/apple/shift.svg0000640006766500116100000002463312130344127023055 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/apple/alt.svg0000640006766500116100000002547412130344127022524 0ustar scottkirkwoodeng00000000000000 image/svg+xml option alt key-mon-1.17/src/keymon/themes/apple/mouse-indicator.svg0000640006766500116100000000453212130344127025036 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/apple/two-line-wide.svg0000640006766500116100000002652012130344127024421 0ustar scottkirkwoodeng00000000000000 image/svg+xml TOP BOTTOM key-mon-1.17/src/keymon/themes/apple/right-mouse.svg0000640006766500116100000002460012130344127024175 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/apple/scroll-rgt-mouse.svg0000640006766500116100000002135512130344127025154 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/apple/ctrl.svg0000640006766500116100000002465412130344127022707 0ustar scottkirkwoodeng00000000000000 image/svg+xml control key-mon-1.17/src/keymon/themes/apple/multi-char-numpad-template-small.svg0000640006766500116100000002603312130344127030202 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/apple/altgr-small.svg0000640006766500116100000002475312130344127024162 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/apple/altgr.svg0000640006766500116100000002432312130344127023045 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/apple/one-char-template-small.svg0000640006766500116100000002453012130344127026347 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/apple/config0000640006766500116100000000027112130344127022377 0ustar scottkirkwoodeng00000000000000[theme] name = Apple description = A clean, modern theme (Apple version) authors = Daniel G. Taylor license = http://creativecommons.org/licenses/by-sa/3.0/us/ key-mon-1.17/src/keymon/themes/apple/whiteout-72.svg0000640006766500116100000002345712130344127024041 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/apple/ctrl-small.svg0000640006766500116100000002470412130344127024011 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/apple/one-line-wide.svg0000640006766500116100000002520712130344127024372 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/modern/0000750006766500116100000000000012261424504021374 5ustar scottkirkwoodeng00000000000000key-mon-1.17/src/keymon/themes/modern/left-mouse.svg0000640006766500116100000002457612130344127024211 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/modern/meta.svg0000640006766500116100000002671012130344127023047 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/modern/mouse-follower.svg0000640006766500116100000000465412130344127025103 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/modern/multi-char-template.svg0000640006766500116100000002450212130344127025774 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/modern/one-char-template.svg0000640006766500116100000002447612130344127025435 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/modern/scroll-up-mouse.svg0000640006766500116100000003121612130344127025164 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/modern/whiteout-58.svg0000640006766500116100000002330612130344127024221 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/modern/whiteout-48.svg0000640006766500116100000002316012130344127024216 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/modern/one-char-numpad-template.svg0000640006766500116100000002602212130344127026704 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/modern/middle-mouse.svg0000640006766500116100000002460112130344127024502 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/modern/mouse.svg0000640006766500116100000003657412130344127023262 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/modern/scroll-lft-mouse.svg0000640006766500116100000002135712130344127025332 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/modern/shift-small.svg0000640006766500116100000002513212130344127024341 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/modern/alt-small.svg0000640006766500116100000002470312130344127024007 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/modern/scroll-dn-mouse.svg0000640006766500116100000002775612130344127025157 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/modern/shift.svg0000640006766500116100000002463312130344127023240 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/modern/alt.svg0000640006766500116100000002447112130344127022703 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/modern/mouse-indicator.svg0000640006766500116100000000453212130344127025221 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/modern/two-line-wide.svg0000640006766500116100000002652012130344127024604 0ustar scottkirkwoodeng00000000000000 image/svg+xml TOP BOTTOM key-mon-1.17/src/keymon/themes/modern/right-mouse.svg0000640006766500116100000002460012130344127024360 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/modern/scroll-rgt-mouse.svg0000640006766500116100000002135512130344127025337 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/modern/ctrl.svg0000640006766500116100000002465112130344127023067 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/modern/multi-char-numpad-template-small.svg0000640006766500116100000002603312130344127030365 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/modern/altgr-small.svg0000640006766500116100000002475212130344127024344 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/modern/altgr.svg0000640006766500116100000002447212130344127023235 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/modern/one-char-template-small.svg0000640006766500116100000002453012130344127026532 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/modern/config0000640006766500116100000000025212130344127022561 0ustar scottkirkwoodeng00000000000000[theme] name = Modern description = A clean, modern theme authors = Daniel G. Taylor license = http://creativecommons.org/licenses/by-sa/3.0/us/ key-mon-1.17/src/keymon/themes/modern/whiteout-72.svg0000640006766500116100000002345712130344127024224 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/modern/ctrl-small.svg0000640006766500116100000002470412130344127024174 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/modern/one-line-wide.svg0000640006766500116100000002520712130344127024555 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/big-letters/0000750006766500116100000000000012261424504022331 5ustar scottkirkwoodeng00000000000000key-mon-1.17/src/keymon/themes/big-letters/left-mouse.svg0000640006766500116100000004441612261301025025134 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/big-letters/meta.svg0000640006766500116100000002774312261301025024006 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/mouse-follower.svg0000640006766500116100000000465112261301025026030 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/multi-char-template.svg0000640006766500116100000002557012261301025026732 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/big-letters/one-char-template.svg0000640006766500116100000002551612261301025026361 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/big-letters/scroll-up-mouse.svg0000640006766500116100000003244312261301025026117 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/big-letters/whiteout-58.svg0000640006766500116100000002330612261301025025151 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/whiteout-48.svg0000640006766500116100000002316012261301025025146 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/one-char-numpad-template.svg0000640006766500116100000002642712261301025027645 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/big-letters/middle-mouse.svg0000640006766500116100000002550212261301025025433 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/big-letters/multi-char-template-small.svg0000640006766500116100000002560412261301025030036 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/big-letters/mouse.svg0000640006766500116100000002241212261301025024174 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/big-letters/scroll-lft-mouse.svg0000640006766500116100000005545112261301025026264 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/big-letters/shift-small.svg0000640006766500116100000003342012261301025025270 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/alt-small.svg0000640006766500116100000002642512261301025024742 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/scroll-dn-mouse.svg0000640006766500116100000005507112261301025026076 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/big-letters/shift.svg0000640006766500116100000003651412261301025024171 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/alt.svg0000640006766500116100000002616612261301025023636 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/mouse-indicator.svg0000640006766500116100000000576112261301025026156 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/two-line-wide.svg0000640006766500116100000002771612261301025025544 0ustar scottkirkwoodeng00000000000000 image/svg+xml TOP BOTTOM key-mon-1.17/src/keymon/themes/big-letters/right-mouse.svg0000640006766500116100000006342412261301025025317 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/big-letters/scroll-rgt-mouse.svg0000640006766500116100000005543512261301025026275 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/big-letters/ctrl.svg0000640006766500116100000003034612261301025024015 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/multi-char-numpad-template-small.svg0000640006766500116100000002650412261301025031320 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/big-letters/altgr-small.svg0000640006766500116100000003170012261301025025263 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/altgr.svg0000640006766500116100000003121612261301025024157 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/one-char-template-small.svg0000640006766500116100000002556512261301025027473 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/big-letters/config0000640006766500116100000000036712261301025023520 0ustar scottkirkwoodeng00000000000000[theme] name = Big letter description = A clean, highly visible theme based on Modern theme by Daniel G. Taylor authors = Kārlis Kalviškis license = http://creativecommons.org/licenses/by-sa/3.0/us/ version = 2013.12.30 key-mon-1.17/src/keymon/themes/big-letters/whiteout-72.svg0000640006766500116100000002345712261301025025154 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/ctrl-small.svg0000640006766500116100000003213612261301025025122 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/big-letters/one-line-wide.svg0000640006766500116100000002552712261301025025512 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear/0000750006766500116100000000000012261424504021176 5ustar scottkirkwoodeng00000000000000key-mon-1.17/src/keymon/themes/clear/left-mouse.svg0000640006766500116100000002457612130344127024013 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear/meta.svg0000640006766500116100000002746712130344127022663 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear/mouse-follower.svg0000640006766500116100000000466312130344127024705 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear/multi-char-template.svg0000640006766500116100000002560312130344127025601 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear/one-char-template.svg0000640006766500116100000002557712130344127025242 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear/scroll-up-mouse.svg0000640006766500116100000003121612130344127024766 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear/whiteout-58.svg0000640006766500116100000002273112130344127024024 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear/whiteout-48.svg0000640006766500116100000002273012130344127024022 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear/one-char-numpad-template.svg0000640006766500116100000003020612130344127026505 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/clear/middle-mouse.svg0000640006766500116100000002460112130344127024304 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear/mouse.svg0000640006766500116100000003715212130344127023055 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear/scroll-lft-mouse.svg0000640006766500116100000002135712130344127025134 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear/shift-small.svg0000640006766500116100000002606512130344127024151 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/clear/alt-small.svg0000640006766500116100000002557612130344127023622 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/clear/scroll-dn-mouse.svg0000640006766500116100000002775612130344127024761 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear/shift.svg0000640006766500116100000002545312130344127023043 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/clear/config~0000640006766500116100000000027612130344127022567 0ustar scottkirkwoodeng00000000000000[theme] name = Ubuntu-clear description = A clean, modern theme (Ubuntu color) authors = Nenad S. Lazich license = http://creativecommons.org/licenses/by-sa/3.0/us/ key-mon-1.17/src/keymon/themes/clear/alt.svg0000640006766500116100000002523412130344127022503 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/clear/mouse-indicator.svg0000640006766500116100000000475612130344127025033 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear/two-line-wide.svg0000640006766500116100000002754312130344127024414 0ustar scottkirkwoodeng00000000000000 image/svg+xml TOP BOTTOM key-mon-1.17/src/keymon/themes/clear/right-mouse.svg0000640006766500116100000002460012130344127024162 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear/scroll-rgt-mouse.svg0000640006766500116100000002135512130344127025141 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear/ctrl.svg0000640006766500116100000002546512130344127022675 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/clear/multi-char-numpad-template-small.svg0000640006766500116100000003055112130344127030167 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/clear/altgr-small.svg0000640006766500116100000002562012130344127024141 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/clear/altgr.svg0000640006766500116100000002533012130344127023031 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/clear/one-char-template-small.svg0000640006766500116100000002561112130344127026335 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear/config0000640006766500116100000000025012130344127022361 0ustar scottkirkwoodeng00000000000000[theme] name = Clear description = A clean, modern theme authors = Nenad S. Lazich license = http://creativecommons.org/licenses/by-sa/3.0/us/ key-mon-1.17/src/keymon/themes/clear/whiteout-72.svg0000640006766500116100000002322512130344127024017 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear/ctrl-small.svg0000640006766500116100000002560412130344127023776 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/clear/one-line-wide.svg0000640006766500116100000002621412130344127024356 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/oblivion/0000750006766500116100000000000012261424504021731 5ustar scottkirkwoodeng00000000000000key-mon-1.17/src/keymon/themes/oblivion/left-mouse.svg0000640006766500116100000002457612130344127024546 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/oblivion/meta.svg0000640006766500116100000002671012130344127023404 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/oblivion/mouse-follower.svg0000640006766500116100000000465412130344127025440 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/oblivion/multi-char-template.svg0000640006766500116100000002452012130344127026331 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/oblivion/one-char-template.svg0000640006766500116100000002451712130344127025766 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/oblivion/scroll-up-mouse.svg0000640006766500116100000003121612130344127025521 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/oblivion/whiteout-58.svg0000640006766500116100000002330612130344127024556 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/oblivion/whiteout-48.svg0000640006766500116100000002316012130344127024553 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/oblivion/one-char-numpad-template.svg0000640006766500116100000002605212130344127027244 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/oblivion/middle-mouse.svg0000640006766500116100000002460112130344127025037 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/oblivion/mouse.svg0000640006766500116100000003637312130344127023614 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/oblivion/scroll-lft-mouse.svg0000640006766500116100000002135712130344127025667 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/oblivion/shift-small.svg0000640006766500116100000002516712130344127024706 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/oblivion/alt-small.svg0000640006766500116100000002474012130344127024345 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/oblivion/scroll-dn-mouse.svg0000640006766500116100000002775612130344127025514 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/oblivion/shift.svg0000640006766500116100000002464212130344127023575 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/oblivion/alt.svg0000640006766500116100000002451012130344127023232 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/oblivion/mouse-indicator.svg0000640006766500116100000000453212130344127025556 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/oblivion/two-line-wide.svg0000640006766500116100000002654112130344127025144 0ustar scottkirkwoodeng00000000000000 image/svg+xml TOP BOTTOM key-mon-1.17/src/keymon/themes/oblivion/right-mouse.svg0000640006766500116100000002460012130344127024715 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/oblivion/scroll-rgt-mouse.svg0000640006766500116100000002135512130344127025674 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/oblivion/ctrl.svg0000640006766500116100000002467012130344127023425 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/oblivion/multi-char-numpad-template-small.svg0000640006766500116100000002606112130344127030723 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/oblivion/altgr-small.svg0000640006766500116100000002477212130344127024703 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/oblivion/altgr.svg0000640006766500116100000002451012130344127023563 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/oblivion/one-char-template-small.svg0000640006766500116100000002454712130344127027077 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/oblivion/config0000640006766500116100000000027312130344127023121 0ustar scottkirkwoodeng00000000000000[theme] name = Oblivion description = A clean, modern theme (dark version) authors = Daniel G. Taylor license = http://creativecommons.org/licenses/by-sa/3.0/us/ key-mon-1.17/src/keymon/themes/oblivion/whiteout-72.svg0000640006766500116100000002345712130344127024561 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/oblivion/ctrl-small.svg0000640006766500116100000002474212130344127024533 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/oblivion/one-line-wide.svg0000640006766500116100000002522612130344127025113 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/classic/0000750006766500116100000000000012261424504021531 5ustar scottkirkwoodeng00000000000000key-mon-1.17/src/keymon/themes/classic/left-mouse.svg0000640006766500116100000002107612130344127024336 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/classic/meta.svg0000640006766500116100000003567512130344127023216 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/classic/mouse-follower.svg0000640006766500116100000000464012130344127025233 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/classic/multi-char-template.svg0000640006766500116100000002413412130344127026132 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/classic/one-char-template.svg0000640006766500116100000002405512130344127025563 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/classic/scroll-up-mouse.svg0000640006766500116100000002126712130344127025326 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/classic/whiteout-58.svg0000640006766500116100000001533212130344127024356 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/classic/whiteout-48.svg0000640006766500116100000001456112130344127024360 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/classic/one-char-numpad-template.svg0000640006766500116100000002371512130344127027047 0ustar scottkirkwoodeng00000000000000 image/svg+xml & Num key-mon-1.17/src/keymon/themes/classic/middle-mouse.svg0000640006766500116100000001766312130344127024651 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/classic/multi-char-template-small.svg0000640006766500116100000002416012130344127027237 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/classic/mouse.svg0000640006766500116100000003515712130344127023413 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/classic/scroll-lft-mouse.svg0000640006766500116100000002135712130344127025467 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/classic/shift-small.svg0000640006766500116100000002172412130344127024501 0ustar scottkirkwoodeng00000000000000 image/svg+xml Shift key-mon-1.17/src/keymon/themes/classic/alt-small.svg0000640006766500116100000002215612130344127024144 0ustar scottkirkwoodeng00000000000000 image/svg+xml Alt key-mon-1.17/src/keymon/themes/classic/scroll-dn-mouse.svg0000640006766500116100000002126412130344127025300 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/classic/shift.svg0000640006766500116100000002245212130344127023372 0ustar scottkirkwoodeng00000000000000 image/svg+xml Shift key-mon-1.17/src/keymon/themes/classic/alt.svg0000640006766500116100000002203212130344127023027 0ustar scottkirkwoodeng00000000000000 image/svg+xml Alt key-mon-1.17/src/keymon/themes/classic/mouse-indicator.svg0000640006766500116100000000453212130344127025356 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/classic/two-line-wide.svg0000640006766500116100000002303112130344127024733 0ustar scottkirkwoodeng00000000000000 image/svg+xml TOP BOTTOM key-mon-1.17/src/keymon/themes/classic/right-mouse.svg0000640006766500116100000002106612130344127024520 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/classic/scroll-rgt-mouse.svg0000640006766500116100000002135512130344127025474 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/classic/ctrl.svg0000640006766500116100000002203412130344127023215 0ustar scottkirkwoodeng00000000000000 image/svg+xml Ctrl key-mon-1.17/src/keymon/themes/classic/multi-char-numpad-template-small.svg0000640006766500116100000002310412130344127030516 0ustar scottkirkwoodeng00000000000000 image/svg+xml & Num key-mon-1.17/src/keymon/themes/classic/altgr-small.svg0000640006766500116100000002224412130344127024473 0ustar scottkirkwoodeng00000000000000 image/svg+xml AltGr key-mon-1.17/src/keymon/themes/classic/two-line-wide-small.svg0000640006766500116100000002305212130344127026044 0ustar scottkirkwoodeng00000000000000 image/svg+xml TOP BOTTOM key-mon-1.17/src/keymon/themes/classic/altgr.svg0000640006766500116100000002203712130344127023365 0ustar scottkirkwoodeng00000000000000 image/svg+xml AltGr key-mon-1.17/src/keymon/themes/classic/one-char-template-small.svg0000640006766500116100000002455112130344127026672 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/classic/config0000640006766500116100000000026312130344127022720 0ustar scottkirkwoodeng00000000000000[theme] name = Classic description = The classic Key Status Monitor theme authors = Jakub (jimmac) Steiner license = http://www.gnu.org/licenses/gpl-2.0.html key-mon-1.17/src/keymon/themes/classic/whiteout-72.svg0000640006766500116100000001434612130344127024356 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/classic/ctrl-small.svg0000640006766500116100000002217112130344127024325 0ustar scottkirkwoodeng00000000000000 image/svg+xml Ctrl key-mon-1.17/src/keymon/themes/classic/one-line-wide.svg0000640006766500116100000002170512130344127024711 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear-ubuntu/0000750006766500116100000000000012261424504022516 5ustar scottkirkwoodeng00000000000000key-mon-1.17/src/keymon/themes/clear-ubuntu/left-mouse.svg0000640006766500116100000002460312130344127025322 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-ubuntu/meta.svg0000640006766500116100000003242512130344127024171 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-ubuntu/mouse-follower.svg0000640006766500116100000000466312130344127026225 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-ubuntu/multi-char-template.svg0000640006766500116100000002560312130344127027121 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear-ubuntu/one-char-template.svg0000640006766500116100000002557712130344127026562 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear-ubuntu/scroll-up-mouse.svg0000640006766500116100000003121212130344127026302 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-ubuntu/whiteout-58.svg0000640006766500116100000002273112130344127025344 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-ubuntu/whiteout-48.svg0000640006766500116100000002273012130344127025342 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-ubuntu/one-char-numpad-template.svg0000640006766500116100000003020612130344127030025 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/clear-ubuntu/middle-mouse.svg0000640006766500116100000002460612130344127025631 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-ubuntu/mouse.svg0000640006766500116100000003717612130344127024403 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-ubuntu/scroll-lft-mouse.svg0000640006766500116100000002135712130344127026454 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-ubuntu/shift-small.svg0000640006766500116100000002606512130344127025471 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/clear-ubuntu/alt-small.svg0000640006766500116100000002557612130344127025142 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/clear-ubuntu/scroll-dn-mouse.svg0000640006766500116100000002775212130344127026275 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-ubuntu/shift.svg0000640006766500116100000002545312130344127024363 0ustar scottkirkwoodeng00000000000000 image/svg+xml shift key-mon-1.17/src/keymon/themes/clear-ubuntu/alt.svg0000640006766500116100000002523412130344127024023 0ustar scottkirkwoodeng00000000000000 image/svg+xml alt key-mon-1.17/src/keymon/themes/clear-ubuntu/mouse-indicator.svg0000640006766500116100000000475512130344127026352 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-ubuntu/two-line-wide.svg0000640006766500116100000002754312130344127025734 0ustar scottkirkwoodeng00000000000000 image/svg+xml TOP BOTTOM key-mon-1.17/src/keymon/themes/clear-ubuntu/right-mouse.svg0000640006766500116100000002460512130344127025507 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-ubuntu/scroll-rgt-mouse.svg0000640006766500116100000002135512130344127026461 0ustar scottkirkwoodeng00000000000000 image/svg+xml Scott Kirkwood key-mon-1.17/src/keymon/themes/clear-ubuntu/ctrl.svg0000640006766500116100000002546512130344127024215 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/clear-ubuntu/multi-char-numpad-template-small.svg0000640006766500116100000003055112130344127031507 0ustar scottkirkwoodeng00000000000000 image/svg+xml & num key-mon-1.17/src/keymon/themes/clear-ubuntu/altgr-small.svg0000640006766500116100000002562012130344127025461 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/clear-ubuntu/altgr.svg0000640006766500116100000002533012130344127024351 0ustar scottkirkwoodeng00000000000000 image/svg+xml altgr key-mon-1.17/src/keymon/themes/clear-ubuntu/one-char-template-small.svg0000640006766500116100000002561112130344127027655 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/src/keymon/themes/clear-ubuntu/config0000640006766500116100000000027612130344127023711 0ustar scottkirkwoodeng00000000000000[theme] name = Clear-Ubuntu description = A clean, modern theme (Ubuntu color) authors = Nenad S. Lazich license = http://creativecommons.org/licenses/by-sa/3.0/us/ key-mon-1.17/src/keymon/themes/clear-ubuntu/whiteout-72.svg0000640006766500116100000002322512130344127025337 0ustar scottkirkwoodeng00000000000000 image/svg+xml key-mon-1.17/src/keymon/themes/clear-ubuntu/ctrl-small.svg0000640006766500116100000002560412130344127025316 0ustar scottkirkwoodeng00000000000000 image/svg+xml ctrl key-mon-1.17/src/keymon/themes/clear-ubuntu/one-line-wide.svg0000640006766500116100000002621412130344127025676 0ustar scottkirkwoodeng00000000000000 image/svg+xml & key-mon-1.17/README.rst0000640006766500116100000000202412130344127016215 0ustar scottkirkwoodeng00000000000000======= Key-mon ======= A screencast utility that displays your keyboard and mouse status Key-mon is useful for teaching since it shows the current status of your keyboard and mouse and you use them in another application. No longer do you need to say 'Now I'm pressing the Ctrl-D key', your students can just see the keystroke for themselves. Home Page --------- You can find key-mon hosted at: http://code.google.com/p/key-mon You can file bugs at: http://code.google.com/p/key-mon/issues/list Latest downloads can be found at: http://code.google.com/p/key-mon/downloads/list Requirements ------------ This program requires other libraries which you may or may not have installed. * python-xlib - Interface for Python to the X11 Protocol (http://python-xlib.sourceforge.net/) * python-gtk2 - Python bindings for the GTK+ widget set (http://www.pygtk.org/) License ------- Apache 2.0 You can find it in the /home/scottkirkwood/20p/key-mon/LICENSE-2.0.txt file. -- file generated by `pybdist`.key-mon-1.17/PKG-INFO0000640006766500116100000000172712261424504015637 0ustar scottkirkwoodeng00000000000000Metadata-Version: 1.1 Name: key-mon Version: 1.17 Summary: A screencast utility that displays your keyboard and mouse status Home-page: http://code.google.com/p/key-mon Author: Scott Kirkwood Author-email: scott+keymon@forusers.com License: Apache 2.0 Download-URL: http://key-mon.googlecode.com/files/key-mon-1.17.zip Description: Key-mon is useful for teaching since it shows the current status of your keyboard and mouse and you use them in another application. No longer do you need to say 'Now I'm pressing the Ctrl-D key', your students can just see the keystroke for themselves. Keywords: keyboard status monitor education Platform: POSIX Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: X11 Applications Classifier: Intended Audience :: Education Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Topic :: Education :: Computer Aided Instruction (CAI) key-mon-1.17/INSTALL.pt_BR.rst0000640006766500116100000000172112130344127017376 0ustar scottkirkwoodeng00000000000000================== Installing key-mon ================== Downloading ----------- You will always find the latest version at: http://code.google.com/p/key-mon/downloads/list If you prefer you can clone repository from:: hg clone http://key-mon.code.google.com/hg key-mon Installation ------------ To install using ``pip``,:: $ pip install key-mon To install using ``easy_install``,:: $ easy_install key-mon To install from .deb package:: $ sudo dpkg -i key-mon*.deb If you get errors like Package key-mon depends on XXX; however it is not installed. $ sudo apt-get -f install Should install everything you need, then run: $ sudo dpkg -i key-mon*.deb # again Dependancies ------------ This program requires:: * python-xlib - Interface for Python to the X11 Protocol (http://python-xlib.sourceforge.net/) * python-gtk2 - Python bindings for the GTK+ widget set (http://www.pygtk.org/) -- file generated by `pybdist`.key-mon-1.17/COPYING0000640006766500116100000002613612130344127015573 0ustar scottkirkwoodeng00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. key-mon-1.17/man/0000750006766500116100000000000012261424504015305 5ustar scottkirkwoodeng00000000000000key-mon-1.17/man/key-mon.pt_BR.10000640006766500116100000000743212261424503017761 0ustar scottkirkwoodeng00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.4. .TH KEYMON "1" "January 2014" "Keymon version 1.17." "User Commands" .SH NAME Keymon \- Keyboard and mouse monitor window for GTK. .SH SYNOPSIS .B key-mon [options] .SH OPTIONS .TP \fB\-h\fR, \fB\-\-help\fR show this help message and exit .TP \fB\-s\fR, \fB\-\-smaller\fR Make the dialog 25% smaller than normal. .TP \fB\-l\fR, \fB\-\-larger\fR Make the dialog 25% larger than normal. .TP \fB\-m\fR, \fB\-\-meta\fR Show the meta (windows) key. .TP \fB\-\-nometa\fR Opposite of \fB\-\-meta\fR .TP \fB\-\-mouse\fR Show the mouse. .TP \fB\-\-nomouse\fR Opposite of \fB\-\-mouse\fR .TP \fB\-\-shift\fR Show shift key. .TP \fB\-\-noshift\fR Opposite of \fB\-\-shift\fR .TP \fB\-\-ctrl\fR Show the ctrl key. .TP \fB\-\-noctrl\fR Opposite of \fB\-\-ctrl\fR .TP \fB\-\-alt\fR Show the alt key. .TP \fB\-\-noalt\fR Opposite of \fB\-\-alt\fR .TP \fB\-\-scale\fR=\fISCALE\fR Scale the dialog. ex. 2.0 is 2 times larger, 0.5 is half the size. Defaults to 1.0 .TP \fB\-\-key\-timeout\fR=\fIKEY_TIMEOUT\fR Timeout before key returns to unpressed image. Defaults to 0.5 .TP \fB\-\-mouse\-timeout\fR=\fIMOUSE_TIMEOUT\fR Timeout before mouse returns to unpressed image. Defaults to 0.2 .TP \fB\-\-visible\-click\-timeout\fR=\fIVISIBLE_CLICK_TIMEOUT\fR Timeout before highly visible click disappears. Defaults to 0.2 .TP \fB\-\-decorated\fR Show decoration .TP \fB\-\-nodecorated\fR Opposite of \fB\-\-decorated\fR .TP \fB\-\-backgroundless\fR Show only buttons .TP \fB\-\-nobackgroundless\fR Opposite of \fB\-\-backgroundless\fR .TP \fB\-\-no\-press\-fadeout\fR=\fINO_PRESS_FADEOUT\fR Fadeout the window after a period with no key press. Defaults to 0.0 seconds (Experimental) .TP \fB\-\-only_combo\fR Show only key combos (ex. Control\-A) .TP \fB\-\-noonly_combo\fR Opposite of \fB\-\-only_combo\fR .TP \fB\-\-sticky\fR Sticky mode .TP \fB\-\-nosticky\fR Opposite of \fB\-\-sticky\fR .TP \fB\-\-visible_click\fR Show where you clicked .TP \fB\-\-novisible_click\fR Opposite of \fB\-\-visible_click\fR .TP \fB\-\-follow_mouse\fR Show the mouse more visibly .TP \fB\-\-nofollow_mouse\fR Opposite of \fB\-\-follow_mouse\fR .TP \fB\-\-kbdfile\fR=\fIKBD_FILE\fR Use this kbd filename. .TP \fB\-\-swap\fR Swap the mouse buttons. .TP \fB\-\-noswap\fR Opposite of \fB\-\-swap\fR .TP \fB\-\-emulate\-middle\fR When you press the left, and right mouse buttons at the same time, it displays as a middle mouse button click. .TP \fB\-\-noemulate\-middle\fR Opposite of \fB\-\-emulate\-middle\fR .TP \fB\-v\fR, \fB\-\-version\fR Show version information and exit. .TP \fB\-t\fR THEME, \fB\-\-theme\fR=\fITHEME\fR The theme to use when drawing status images (ex. "\-t apple"). .TP \fB\-\-list\-themes\fR List available themes .TP \fB\-\-old\-keys\fR=\fIOLD_KEYS\fR How many historical keypresses to show (defaults to 0) .TP \fB\-\-reset\fR Reset all options to their defaults. .TP \fB\-\-opacity\fR=\fIOPACITY\fR Opacity of window .TP \fB\-\-loglevel\fR=\fILOGLEVEL\fR Logging level .TP \fB\-d\fR, \fB\-\-debug\fR Output debugging information. Shorthand for \fB\-\-loglevel\fR=\fIdebug\fR .TP \fB\-\-screenshot\fR=\fISCREENSHOT\fR Create a "screenshot.png" and exit. Pass a comma separated list of keys to simulate(ex. "KEY_A,KEY_LEFTCTRL"). .SH DESCRIPTON .B Keymon is a program to help in teaching or podcasting by showing the current status of the mouse buttons and keyboard. .PP .B Keymon creates a small, borderless window which always stays topmost and monitors the keystrokes and mouse buttons used at any time in any program. Configuration files are saved in ~/.config/key-mon/. .SH AUTHOR Written by Scott Kirkwood (scott+keymon@forusers.com) .SH "SEE ALSO" Full documentation for .B keymon is available at .IP .B http://code.google.com/p/key-mon .PP Send bugs to .IP .B http://code.google.com/p/key-mon/issues/list .PP key-mon-1.17/man/key-mon.10000640006766500116100000000743212261424503016754 0ustar scottkirkwoodeng00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.4. .TH KEYMON "1" "January 2014" "Keymon version 1.17." "User Commands" .SH NAME Keymon \- Keyboard and mouse monitor window for GTK. .SH SYNOPSIS .B key-mon [options] .SH OPTIONS .TP \fB\-h\fR, \fB\-\-help\fR show this help message and exit .TP \fB\-s\fR, \fB\-\-smaller\fR Make the dialog 25% smaller than normal. .TP \fB\-l\fR, \fB\-\-larger\fR Make the dialog 25% larger than normal. .TP \fB\-m\fR, \fB\-\-meta\fR Show the meta (windows) key. .TP \fB\-\-nometa\fR Opposite of \fB\-\-meta\fR .TP \fB\-\-mouse\fR Show the mouse. .TP \fB\-\-nomouse\fR Opposite of \fB\-\-mouse\fR .TP \fB\-\-shift\fR Show shift key. .TP \fB\-\-noshift\fR Opposite of \fB\-\-shift\fR .TP \fB\-\-ctrl\fR Show the ctrl key. .TP \fB\-\-noctrl\fR Opposite of \fB\-\-ctrl\fR .TP \fB\-\-alt\fR Show the alt key. .TP \fB\-\-noalt\fR Opposite of \fB\-\-alt\fR .TP \fB\-\-scale\fR=\fISCALE\fR Scale the dialog. ex. 2.0 is 2 times larger, 0.5 is half the size. Defaults to 1.0 .TP \fB\-\-key\-timeout\fR=\fIKEY_TIMEOUT\fR Timeout before key returns to unpressed image. Defaults to 0.5 .TP \fB\-\-mouse\-timeout\fR=\fIMOUSE_TIMEOUT\fR Timeout before mouse returns to unpressed image. Defaults to 0.2 .TP \fB\-\-visible\-click\-timeout\fR=\fIVISIBLE_CLICK_TIMEOUT\fR Timeout before highly visible click disappears. Defaults to 0.2 .TP \fB\-\-decorated\fR Show decoration .TP \fB\-\-nodecorated\fR Opposite of \fB\-\-decorated\fR .TP \fB\-\-backgroundless\fR Show only buttons .TP \fB\-\-nobackgroundless\fR Opposite of \fB\-\-backgroundless\fR .TP \fB\-\-no\-press\-fadeout\fR=\fINO_PRESS_FADEOUT\fR Fadeout the window after a period with no key press. Defaults to 0.0 seconds (Experimental) .TP \fB\-\-only_combo\fR Show only key combos (ex. Control\-A) .TP \fB\-\-noonly_combo\fR Opposite of \fB\-\-only_combo\fR .TP \fB\-\-sticky\fR Sticky mode .TP \fB\-\-nosticky\fR Opposite of \fB\-\-sticky\fR .TP \fB\-\-visible_click\fR Show where you clicked .TP \fB\-\-novisible_click\fR Opposite of \fB\-\-visible_click\fR .TP \fB\-\-follow_mouse\fR Show the mouse more visibly .TP \fB\-\-nofollow_mouse\fR Opposite of \fB\-\-follow_mouse\fR .TP \fB\-\-kbdfile\fR=\fIKBD_FILE\fR Use this kbd filename. .TP \fB\-\-swap\fR Swap the mouse buttons. .TP \fB\-\-noswap\fR Opposite of \fB\-\-swap\fR .TP \fB\-\-emulate\-middle\fR When you press the left, and right mouse buttons at the same time, it displays as a middle mouse button click. .TP \fB\-\-noemulate\-middle\fR Opposite of \fB\-\-emulate\-middle\fR .TP \fB\-v\fR, \fB\-\-version\fR Show version information and exit. .TP \fB\-t\fR THEME, \fB\-\-theme\fR=\fITHEME\fR The theme to use when drawing status images (ex. "\-t apple"). .TP \fB\-\-list\-themes\fR List available themes .TP \fB\-\-old\-keys\fR=\fIOLD_KEYS\fR How many historical keypresses to show (defaults to 0) .TP \fB\-\-reset\fR Reset all options to their defaults. .TP \fB\-\-opacity\fR=\fIOPACITY\fR Opacity of window .TP \fB\-\-loglevel\fR=\fILOGLEVEL\fR Logging level .TP \fB\-d\fR, \fB\-\-debug\fR Output debugging information. Shorthand for \fB\-\-loglevel\fR=\fIdebug\fR .TP \fB\-\-screenshot\fR=\fISCREENSHOT\fR Create a "screenshot.png" and exit. Pass a comma separated list of keys to simulate(ex. "KEY_A,KEY_LEFTCTRL"). .SH DESCRIPTON .B Keymon is a program to help in teaching or podcasting by showing the current status of the mouse buttons and keyboard. .PP .B Keymon creates a small, borderless window which always stays topmost and monitors the keystrokes and mouse buttons used at any time in any program. Configuration files are saved in ~/.config/key-mon/. .SH AUTHOR Written by Scott Kirkwood (scott+keymon@forusers.com) .SH "SEE ALSO" Full documentation for .B keymon is available at .IP .B http://code.google.com/p/key-mon .PP Send bugs to .IP .B http://code.google.com/p/key-mon/issues/list .PP key-mon-1.17/README.pt_BR.rst0000640006766500116100000000202412130344127017222 0ustar scottkirkwoodeng00000000000000======= Key-mon ======= A screencast utility that displays your keyboard and mouse status Key-mon is useful for teaching since it shows the current status of your keyboard and mouse and you use them in another application. No longer do you need to say 'Now I'm pressing the Ctrl-D key', your students can just see the keystroke for themselves. Home Page --------- You can find key-mon hosted at: http://code.google.com/p/key-mon You can file bugs at: http://code.google.com/p/key-mon/issues/list Latest downloads can be found at: http://code.google.com/p/key-mon/downloads/list Requirements ------------ This program requires other libraries which you may or may not have installed. * python-xlib - Interface for Python to the X11 Protocol (http://python-xlib.sourceforge.net/) * python-gtk2 - Python bindings for the GTK+ widget set (http://www.pygtk.org/) License ------- Apache 2.0 You can find it in the /home/scottkirkwood/20p/key-mon/LICENSE-2.0.txt file. -- file generated by `pybdist`.key-mon-1.17/icons/0000750006766500116100000000000012261424504015645 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/key-mon.xpm0000640006766500116100000001656612130344127017766 0ustar scottkirkwoodeng00000000000000/* XPM */ static char * keymon_xpm[] = { "32 32 332 2", " c None", ". c #FFFFFF", "+ c #DFDFDF", "@ c #CBCBCA", "# c #E5E4E4", "$ c #F2F1F1", "% c #E9E8E8", "& c #B6B6B5", "* c #908F8F", "= c #F2F1F0", "- c #F2F0EF", "; c #F3F3F2", "> c #F9F9F8", ", c #F5F4F4", "' c #F6F5F5", ") c #F7F6F6", "! c #D6D5D5", "~ c #E7E6E5", "{ c #D5D1D0", "] c #CBC0BF", "^ c #CDC3C2", "/ c #9F9D9C", "( c #7E7E7D", "_ c #D2D1D0", ": c #CECDCC", "< c #D0CECD", "[ c #DFDEDC", "} c #F7F6F5", "| c #D8D7D7", "1 c #C6C5C4", "2 c #C1C0BF", "3 c #C2C1C1", "4 c #C2C1C0", "5 c #C2C2C1", "6 c #C3C2C1", "7 c #C3C1C1", "8 c #C8C8C8", "9 c #DCDCDB", "0 c #EEEEED", "a c #B7B3B2", "b c #734C4C", "c c #703838", "d c #703636", "e c #764344", "f c #A8A2A2", "g c #949697", "h c #B6B6B6", "i c #B6B7B7", "j c #BABBBA", "k c #B9BAB9", "l c #A09F9F", "m c #DCDBDB", "n c #F0EEEE", "o c #B9B7B7", "p c #AFAEAE", "q c #B1B1B1", "r c #AFAFAF", "s c #AFAFB0", "t c #B0AFB0", "u c #B0B0B0", "v c #B2B2B1", "w c #B3B2B2", "x c #B3B3B3", "y c #B4B4B4", "z c #B4B5B5", "A c #B5B5B5", "B c #BFBEBD", "C c #DEDEDD", "D c #867776", "E c #7E3F3F", "F c #702D2D", "G c #6F2D2D", "H c #763C3C", "I c #A39C9E", "J c #72767B", "K c #C4C7C9", "L c #C8CBCB", "M c #D5D7D7", "N c #DEDEDE", "O c #A2A2A1", "P c #EAE9E9", "Q c #ACABAB", "R c #ADADAE", "S c #B3B3B4", "T c #A9A9AA", "U c #ABABAC", "V c #ACACAD", "W c #ADADAF", "X c #B2B2B2", "Y c #B5B5B6", "Z c #B7B7B7", "` c #B8B8BA", " . c #BBBBBC", ".. c #C1C1C3", "+. c #AEAEAF", "@. c #D5D5D4", "#. c #978282", "$. c #773636", "%. c #702E2E", "&. c #979092", "*. c #52575C", "=. c #BFC3C5", "-. c #D4D5D6", ";. c #DADBDB", ">. c #E2E2E1", ",. c #747473", "'. c #E9EAE8", "). c #AEAEAD", "!. c #A3A3A4", "~. c #A7A7A8", "{. c #AAAAAB", "]. c #B4B4B5", "^. c #B6B6B7", "/. c #C0C0C1", "(. c #CECECF", "_. c #ADADAD", ":. c #D2D2D1", "<. c #998584", "[. c #763536", "}. c #958E91", "|. c #505459", "1. c #BEC2C4", "2. c #787878", "3. c #EAEAE9", "4. c #AEADAD", "5. c #B3B2B3", "6. c #A8A8A9", "7. c #B0B0B1", "8. c #B7B7B8", "9. c #BABABB", "0. c #BDBDBD", "a. c #C1C1C1", "b. c #CCCCCD", "c. c #9A8685", "d. c #783939", "e. c #723131", "f. c #713030", "g. c #773E3F", "h. c #9B9597", "i. c #5E6367", "j. c #C1C4C6", "k. c #C8CACB", "l. c #DADBDA", "m. c #B2B2B3", "n. c #9B9B9C", "o. c #999999", "p. c #ACACAC", "q. c #BCBCBD", "r. c #BDBDBE", "s. c #C4C4C4", "t. c #D1D1D0", "u. c #ACA5A3", "v. c #AC9290", "w. c #A58C8A", "x. c #A28989", "y. c #9F8A8A", "z. c #B0B0B2", "A. c #969A9E", "B. c #BEC2C3", "C. c #C1C4C4", "D. c #CACCCC", "E. c #CFD0CE", "F. c #D8D9D7", "G. c #AEAEAE", "H. c #9F9F9F", "I. c #4A4A4A", "J. c #363636", "K. c #797978", "L. c #C2C2C2", "M. c #C1C1C2", "N. c #C3C3C4", "O. c #C7C7C7", "P. c #CDCDCD", "Q. c #D0CFCE", "R. c #BDBDBC", "S. c #E0E0DE", "T. c #D2D4D3", "U. c #CCCECF", "V. c #C5C9CB", "W. c #C0C5C8", "X. c #C6C9CB", "Y. c #CBCECF", "Z. c #D1D2D2", "`. c #D6D7D6", " + c #DEDFDE", ".+ c #797979", "++ c #EAEAE8", "@+ c #B7B8B7", "#+ c #7D7D7D", "$+ c #424242", "%+ c #2C2C2C", "&+ c #5E5E5E", "*+ c #C5C5C6", "=+ c #C7C7C8", "-+ c #C9C9CA", ";+ c #CCCDCD", ">+ c #ADACAD", ",+ c #BEBEBD", "'+ c #E5E5E4", ")+ c #DDDEDD", "!+ c #D7D9D9", "~+ c #D0D2D4", "{+ c #C9CDCF", "]+ c #C3C8CC", "^+ c #C9CCCF", "/+ c #CFD1D3", "(+ c #E2E2E2", "_+ c #EBEAE8", ":+ c #B9B9BA", "<+ c #C0C0C0", "[+ c #B1B1B2", "}+ c #555555", "|+ c #3B3B3C", "1+ c #2A2A2A", "2+ c #414141", "3+ c #919192", "4+ c #CACACB", "5+ c #CDCDCE", "6+ c #B1B0B1", "7+ c #ADACAC", "8+ c #D0D2D3", "9+ c #CFD1D2", "0+ c #EBE9E8", "a+ c #BBBABB", "b+ c #C2C2C3", "c+ c #A1A1A2", "d+ c #3C3C3C", "e+ c #444445", "f+ c #404040", "g+ c #393939", "h+ c #6D6D6D", "i+ c #C8C8C9", "j+ c #D1D1D1", "k+ c #EAE9E8", "l+ c #949494", "m+ c #7C7C7C", "n+ c #8A8A8A", "o+ c #6A6A6A", "p+ c #6C6C6C", "q+ c #C6C6C6", "r+ c #D0D0D0", "s+ c #D4D4D3", "t+ c #B3B2B1", "u+ c #BEBEBE", "v+ c #BFBFBF", "w+ c #CECECE", "x+ c #D2D2D3", "y+ c #D4D4D4", "z+ c #D6D6D6", "A+ c #AEADAE", "B+ c #CBCBCB", "C+ c #BFBFC0", "D+ c #C3C3C3", "E+ c #C5C5C5", "F+ c #D5D5D5", "G+ c #D8D8D8", "H+ c #DBDBDB", "I+ c #D1D0CF", "J+ c #777776", "K+ c #C0C1C1", "L+ c #CCCCCC", "M+ c #C4C4C5", "N+ c #C9C9C9", "O+ c #CFCFCF", "P+ c #D2D2D2", "Q+ c #DCDDDD", "R+ c #CDD0D1", "S+ c #C0C3C5", "T+ c #BABFC3", "U+ c #C1C5C7", "V+ c #CED0D1", "W+ c #DBDCDB", "X+ c #DEDFDD", "Y+ c #6F6F6E", "Z+ c #E9E9E9", "`+ c #B1B0B0", " @ c #BABABA", ".@ c #C6C6C7", "+@ c #BBBBBB", "@@ c #ABABAB", "#@ c #ACACAB", "$@ c #E9E8E7", "%@ c #A7A6A6", "&@ c #E1E2E2", "*@ c #D3D5D6", "=@ c #C7CACC", "-@ c #C4C8CB", ";@ c #C8CBCD", ">@ c #D8D9D9", ",@ c #DCDDDC", "'@ c #6B6B6A", ")@ c #EFEEED", "!@ c #A5A5A5", "~@ c #A6A6A7", "{@ c #A2A2A3", "]@ c #A1A2A2", "^@ c #A1A0A1", "/@ c #A0A0A0", "(@ c #9F9FA0", "_@ c #9E9E9F", ":@ c #9E9E9E", "<@ c #9D9D9D", "[@ c #A2A3A3", "}@ c #A1A1A0", "|@ c #B4B3B2", "1@ c #DCDBDA", "2@ c #969695", "3@ c #727271", "4@ c #706F6E", "5@ c #707070", "6@ c #70706F", "7@ c #6C6C6B", "8@ c #5F5F5F", "9@ c #F5F4F3", "0@ c #C9C8C7", "a@ c #B0B0AE", "b@ c #A7A7A6", "c@ c #A8A8A7", "d@ c #A8A8A8", "e@ c #A9A8A8", "f@ c #AAA8A8", "g@ c #AAA9A8", "h@ c #AAA9A9", "i@ c #A9A9A9", "j@ c #B3B3B2", "k@ c #CDCDCC", "l@ c #EDECEB", "m@ c #D7D6D5", "n@ c #F7F7F7", "o@ c #F3F2F1", "p@ c #F4F2F1", "q@ c #F4F3F3", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "+ @ # $ % & * % = - - - = ; > , ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ) ", "! ~ { ] ] ^ / ( _ : : < [ - } | 1 2 3 3 3 4 4 4 4 3 3 5 6 7 8 9 ", "0 a b c d e f g h i j k l m n o p q r s r t u v w x y z A A u B ", "C D E F G H I J K L M N @ O P Q R S T U V W s X S Y Z ` ...+.p ", "@.#.$.%.G H &.*.=.L -.;.>.,.'.).S Y !.~.{.V u X ].^.` ./.(.^._.", ":.<.[.%.G H }.|.1.L -.;.>.2.3.4.5.].!.6.{.R +.7.].8.9.0.a.b.Y 4.", ":.c.d.e.f.g.h.i.j.k.-.l.>.2.3.).].8.~.U +.m.n.o.p.q.r./.s.b.y 4.", "t.u.v.w.x.y.z.A.B.C.D.E.F.2.3.G.h 9.{.s m.H.I.J.K.L.M.N.O.P.S _.", "Q.R.S.F.T.U.V.W.X.Y.Z.`. +.+++r @+0.+.S ^.#+$+%+&+m.*+=+-+;+X >+", "Q.,+'+)+!+~+{+]+^+/+-.;.(+2._+u :+<+[+^.Y }+|+1+2+3+4+4+5+5+6+7+", "Q.,+'+)+!+8+{+]+^+9+-.;.>.2.0+q a+b+^.8.c+d+e+f+g+h+i+5+j+5+u 7+", "Q.,+'+)+!+8+{+]+^+9+-.;.>.2.k+v q.*+9.:+l+}+m+n+o+p+q+r+s+5++.7+", "Q.,+'+)+!+8+{+]+^+9+-.;.>.2.k+t+u+i+q.v+:+R L.w+a.A x+y+z+5+A+7+", "Q.,+'+)+!+8+{+]+^+9+-.;.>.K.k+x <+B+C+D+E+O.B+w+r+j+F+G+H+(.V p.", "I+,+'+)+!+8+{+]+^+9+-.;.>.J+k+y K+L+L.M+q+=+N+4+b.w+O+r+P+P.G.p.", "! ).3.Q+!+R+S+T+U+V+-.W+X+Y+Z+`+ @.@r.r.r.q.q.q.q. . . .+@<+@@#@", "$@%@<+&@;.*@=@-@;@-.>@,@H.'@)@q !@~@!.{@]@c+^@/@(@H._@:@<@[@}@|@", ")@1@2@3@4@5@5@5@5@5@6@7@8@G.9@0@a@b@c@c@d@d@e@f@e@e@f@g@h@i@j@k@", "l@)@$@s+Q.Q.Q.Q.Q.Q.Q.Q.m@k+n@o@p@o@o@o@o@o@o@o@o@o@o@o@o@o@p@q@", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "}; key-mon-1.17/icons/key-mon.desktop0000640006766500116100000000070012130344127020612 0ustar scottkirkwoodeng00000000000000[Desktop Entry] Version=1.0 Name=KeyMon GenericName=Keyboard and Mouse Monitor GenericName[pt_BR]=Monitor para mouse e teclado GenericName[tr]=Klavye ve Fare İzleyici Comment=Keyboard and Mouse Monitor for screencasts Comment[pt_BR]=Monitor para mouse e teclado, util para screencasts Comment[tr]=Ekran kayıtları için klavye ve fare izleyici Exec=key-mon Icon=key-mon Terminal=false Type=Application Categories=GTK;Graphics; StartupNotify=true key-mon-1.17/icons/hicolor/0000750006766500116100000000000012261424504017304 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/32x32/0000750006766500116100000000000012261424504020065 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/32x32/apps/0000750006766500116100000000000012261424504021030 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/32x32/apps/key-mon.png0000640006766500116100000000325412261301025023112 0ustar scottkirkwoodeng00000000000000PNG  IHDR szzsIDATXoի.6r;`A(Lb/2)"Rvd5{`̖  ,"ØA`<Mw},&dG)UWs9W?>ī7oɮ]GQ,,,q'O11g8~8Ur_9+w/(P*$I^nPðN(iIyNQc(zo>-in ^V0h4vTA R@cZk99$frrV6iRJ PU_|Z-deeZF!*kPaE)Rz*B/x@=N! "a p#@kR èz>c:,DQt9Wi`nݻw^4XVt^h<ӧk?4_4 Zub,+{7ٸkq\=:ߺ7??OE=sFQtZ+J PZks,..|&{r+'zDoIY;vlɓJF*{y.\ݛKSvvݫbP傔0N> )7sEQV+Wo_ׯHIENDB`key-mon-1.17/icons/hicolor/64x64/0000750006766500116100000000000012261424504020077 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/64x64/apps/0000750006766500116100000000000012261424504021042 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/64x64/apps/key-mon.png0000640006766500116100000000776612261301025023140 0ustar scottkirkwoodeng00000000000000PNG  IHDR@@iqIDATx[]l\ez~3?glq;`8uؔ&$]PZEYjU(\JTPo.D*MEZ5T.Y ϱ$cc3|?8;Iڋ3s|{yXkcm.˗^z}Nb+!֘=܃ZFcZv\.OMOO7ޘ) ر;l6>0DB BpyWZLLL뺥z!R޵ sJ)!ZRPJAJ l6ٳGG}tWM̼y'xP( aӇR 1:u 'Ox5PJ!8SaP/}U`׮]7#<ټ2!Qp1?? J)RmפB0{~s78pJRxY$c`L#vBRכk=RJ?9#GCP`BpK\ݾytiR/J-X!J?W/_SO=={~GB,յA!! ( şѶkc񹹞"w Pܾ}4M0ƒۖזz֨j8z8fg?ϢV[) Ow[+)UmYJizo?<4roѷzAk0CRʺ>p8]%oB@JbFo%iY{)À;gaaaZbM22ĶmÐRe O)IZAs.X[YYAZEZEDF9}4[n\EP@>OR&&&& "iQI4G*J0~uFi.Wq\pJiqEexAHAx3H )581exx8|衇l6!*lpH.0 0ŕ97#ad I |>3g@;vDOO/Ky\zvD X]]fAߗ&Iidgtv1PFzO+1K8mxBXZ&S6Ҁ0 -Dԗi`] `+@X^}}J0&cvv ߞNYLT!M)50 Eۣ-2À.\B4㠷PJ33 ΝevLRl>Uni%J@0~Tۓ_b333PJall /_0ŋ,,,sQTY2 T KYq#9Hc %T qS Bba[x `CRJa,-_x'Zl< K#$X'< X[[\\sA:<_OLS+Io6͂YY^EQtw"LqrSlv CE޿ؼy'O~{B} 7ipSFȊgarZۭt"ΞA޽{111 lj'PVqy0 DUQ!֚^k2J*>)Vك\kMo/u ʲ=*V60mjQRJl_GrBk_?OY~$*'N\j:ݥV}!ifQmjb~ׯ_+qq

ɘqy4!l*0ؿs7\ׅqh1@P!@pn@覈yB}fYp#7GlQ)iMeUmn,*Urt{fF7n/!V?XS"SJ! Ja-]^:sO$h6W#`[W&CY^( !&LgaNhZmL#::??]wz:?0 }Q`Z}?ˡZ,Lhʫbu9#8}4vzL+뺣 NwtŘV@\~ܿR|Ejf0+.^G|3j{T>عs'ֺ077f_u ͛7CqH-秕Ufg}ѣGg}P( uFwRx|&ܽ{㡡VVVavvvۿܺukZr|9ǫWw###4M,..6ƇX@=zjzZKNqB$IBo -s\'RB)%BgϞ\׏ !hZZ[ܸ1ǿ1>kkZ-1?qⓟ+5cR!R @"e&JE4{1icuunw){BXk[i1GA)EXDR WuB^:R5Zk1s$ri8)JJ%sNGX$ @&1m9skSFG?Сw~:R DQR8./7+TDE!"B;%lmmvvhLDV/K׉Ff)(bxx c|NRZu`)f.be1,c9 }+ TYiZֺ/h6H_}!$B@ZŋtΓS){'ֺXTJ%NC)i ާx>%^$ɤ5wZ&''( i{\R #*B%.]4Eћn\,iknNLL|08 )B( !2ӣH"e)%M?fT<&Kq^<|ӧG{pʕ_G3DgIENDB`key-mon-1.17/icons/hicolor/16x16/0000750006766500116100000000000012261424504020071 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/16x16/apps/0000750006766500116100000000000012261424504021034 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/16x16/apps/key-mon.png0000640006766500116100000000115312261301025023112 0ustar scottkirkwoodeng00000000000000PNG  IHDRabKGD pHYs  tIME  *IDAT8˵K[QzCP2du W 8fsi%M4['b]\j 1`Ĥw!&s~ YV>PڏfVWWS-aHj}zp&AّZh\]\^^0?Pu5Zkrx|>/z]NOO""'''2Yqͦ~F" b1bvyjh4 @XDD(Y!ZJ[G+IR""R.> ~pp@: uJ҃ӷ@ϛlo}ZR(PJQ(V$롃0 }L$"VR cp]w,01x ZknS Qpb̏ڄ܉_6771c3= ۟2 kkk(NRy8j]wAvݽט|&x8+y!".0DiN~IENDB`key-mon-1.17/icons/hicolor/48x48/0000750006766500116100000000000012261424504020103 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/48x48/apps/0000750006766500116100000000000012261424504021046 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/48x48/apps/key-mon.png0000640006766500116100000000537012261301025023131 0ustar scottkirkwoodeng00000000000000PNG  IHDR00W IDAThYo3;NcMcB^PZVK@ A*!T/@FB"Iq 9Mh!qj{wk;ٝwx]ԗJi43wvswsvg_oÇO G#\.BȠm۩O>DMMM^jZ=|?йLLLn*> ^y?~W_}R]d  1 Bh~}d`\g !࣏ xq>c!v e(رacl x||Cj DD@R$}L&VX|!DD82ׯ/PC)BHG @]וRi2, 0"0F( 11q/(!Ҳ,ۜsPJ#^'h;ÏPB@@ګ]C>lujm;!hY HH ! BH8Nk#䥔Rs"Rl6bJ&'s7R 3N1c!,e18hLs,2HJ RB9 @͛ 㿀s/1pܶmw~'T*ˢ[k /Bq{vC%B{d27nc~~/uQJu677%!$zY?* 4 0fmEr[Alnc"pfsX^^64ID:zN jUPJfƬpK!vV&aMfh4(JQrG JIgeeQRjҨ9VJV B,/HvP#ca%\,P =\ҸZcYZ6 PJD`b J)pη=w<ϋKqi,,@:]ݧH(Jp,lB^R2+kppПpHʪG"Й0CpEa߾p4R'5CdTJM6㜣D-sX<ᓉRo¬6իWP,1==f (+H=MmBйI}BȈ8Hsn7dC) 2ƶmT*Ux^]]Ƒfeg8aЫ^] !$}^Oz~dёI O?E>EXjC&Ͽd@롐N^F[v ݖC bv*'N@l61uR6Ơ9$Q[h,pI )j $$-4cϞ{C!j(p%2رJuutz_2щ's2Ibyln68wQ@Eɹ 5V?'P.`||Ez:x+U_a3Rkodެz uk8#f(N!N# q8|l6k'x⟜Lد/2r .?{SO=255fS/ zf z='Ν;w""O?ÃsIvlTL)7nw˗s=s\1Ji_jyrmm'Ov~bbsss2/|P(gGR]RB|WsZVWmw;c7W>1.IENDB`key-mon-1.17/icons/hicolor/128x128/0000750006766500116100000000000012261424504020241 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/128x128/apps/0000750006766500116100000000000012261424504021204 5ustar scottkirkwoodeng00000000000000key-mon-1.17/icons/hicolor/128x128/apps/key-mon.png0000640006766500116100000002276512261301025023276 0ustar scottkirkwoodeng00000000000000PNG  IHDR>a IDATx}Y߯:(Ri4%ʲhhӱ,"RN>dayIq'`XB F@ծCvƲ(3黫CUW=ChLwuUMWUtMtMtMtMtMtMtMtMtMtMtMtMt]Aä^m @\~].q6𵺺j\z՝;D_׸~Z4r.^pIIV,狢(9+<_8NvensirmۜmێeY=00z+uz^o_]xq}}}looSAxGWx>z~eerDQ( qض q"/ui^ut:?Gma@u}hfZ7www?{{{^Ϝy(iەBlۆC`@  N01Mhllll7|󩧟~%)ٗw}ϟ?'N<\VC8.+Fop]ȲBp79'O~}}~»V܅ }sϗA 8.$X4@g8y Rϗѣ'v98}񬍟'\.7$B`Kok׮ƍ4 KKKE1Q/Aɲ|ڻAxڵkSҗɓ'|qiicmz$I!<ӂghT`}6 [[[!d  IHe~aa~+_O9cgWVw 4@6O2 8mc;{]t.pܹsX,2q'FvnT*LӄmoObεϞ9sǯ8?? YL! iԹY09qVG_8{,#Օ8'ƹ<Ée^C:xMܺu>Q,aYF!?|>ꫯ m=.//}pii ,g>g:x&s Cq<_A}{9IFr5}I~~|9NB.\lc4{t]i BZ^vp \n;w}7$IۅL6QāFucAW)iOy(x6X`|m;E fڌg>TV3 I0 /EP xŗp'%$/~g|ɿ y <"l(糌2n9|mۃjykkgSNqGy4i|Xq|P9,-sSi:vU4 \.BDQ, [g׿(Ń7|%A?PrL[q)t:*r4MNv[A68A'8|0N:~{lGmH-8z=]rj*?(YIO A,Ke|q{ ܉t9CPT"I|4ͯU AB1K5$Dຮ麮4M\|;;;Hv1??sAdѤ߸o~ D?U$u\NCUR g6o71I u>!bss7o dkk*TUCT>p?۶IF\\'FI K/]- d9O}Sxf UUI~[m M*^JC݁PVa}vUp s@ 0  fƹ=-vku]Te "=躊~,oBUUh4#砉u]u]#?(mZ c~_CӁm;q(+8 I?xONR=?'8CTBBR ٬ر;o|hۉb 1sAG^BґTpDRUL<HjH0MSm<~iտpjU.na6dYƅ ^KjX YpLO9EQj@g|>z}b?H(ض%q.m%}N ҟA,a0 i²,z=BY>3[m$AI]ӆd~_>(t:q)G,R4h܂O>.㪀 %Lݶm?_ QyQR ```8{f?)EV,9MB d޻1"p8!$J@%"^@,ˑi〞Hz6G}:!aē϶m4MdPbRaD$@R-NrK~ ZWuL lA?Ƞ~iOhkTHR> B|3ci*7/XGd3pRu]ӌ{# 8-hWi})sv;v{Tg6if%~,b0Kq@d!Ĩ7ogEE=`x:Q'nD? z`^@ѵB>=A{}pAQf `YQ>2ly4X=eh~qj40>!h2hww 0B,+t,b`mA6TUŕ+W`&3Ғ&)x)MbaݚngqEELׇ̠$ va <|BXOjnt:aY4}㍶@E@^/,pvo " D{@d K m$I8n @7MhZ<]_20B)v\$!aB.b\bnmm_G߇a$ |>LrЅ,BC.)$Q@A2p˲B@ hCo&L r<뚳s* >y1Z(q@Vd\.{ m,--%b?0JZbffJ%FVbeAfy QSIxx UU˲8q8Z?>{U?!eT*Z] 6<;GDG+э8aD$?8bDXOMBX<( XZZ ;(^bnۑ Fb~v91-j V~AױmN F9T*{VE1jp'1ߥI$?K(KxRPT:TJ @zZ]Ġ (ʔ? 'KӮDo8K@OڶQ@2$?*֟sU^bbj 7RYض{/VP@AIfJ\ql${`?I=* H r dYDQ > m5} x(MR\I ,iIFD#Nd @v˟sL/ BB) m ^gJ!@~%a phVx|Λ}IA Dw{0 CU0 :򞟟 T-|>*KhJQ."OsZ)2;sP$kCcww7T:t,(ߺu u \@@AT8< |k!tƳ@+m0$v@Z@yF F ݸ<fNרxp ?I Itl WG:YuåapݒV:BwR; `#1)@$t.X`Rn KQ&!įkuLݿrJ%ؠ'ϣu3?P\"d-k ~2Zi6@Lbq|Pt~{{uB8躎bQx^`XRY/3H0!^ðO%a q>IO" d&!{NdWAHlIeaw뺎9%jVOA)I9TU8=4MlmmL*3 IHhN=LO8-;5qH>' 7EA^˺e Ik(ti@Vq=n@ߨ@pEFq 2DUniaH.G\ H gT*4͡ o⃢B$`Y3$2>N1MBJ9b&bYvr9ln{ Pg^T n  741 q],'0B Vgаˇ//B T*er1 Ə Ճ$IT@dYFdV)X(],!Pi}@5xb a0AII+Ԋ\NO\?#=À\,.. u8mdN'Q|֠<|pV7* |;$Pƈ@rb '9jAUU(JT*5=ǽqu&Dq"$wYHDce,D3{(%+r 4nrR|ggg~|s][\\[ȼ_Yn*$I׆$877W ?Xg?'u ')O \yYXC#^ry0 B>R5|[eg?BpB kh4M߳ #Fbw B Q̍ ;d9%!r^{W#A-H?-<*rj:i5 8N4<'K]kHRxwdQS $R:Kч-s#AwXqXs1x04n >m?M -`?fw 1juچaXʛ$=1gI&O= |cj"UU{aY"HPʲKR̰m[OnvYٿx|(s^+/ T*[q2*[=iq uݾixw\ Z<ܐAIn$KIf '!Q!"$IZ{,W qEǹuR;Ut?~ƍ0@ët5& f5a3u][wq(I3@EQTEQޞf L̒OL k3?kpksss7ޞEjTU^ƅ|sq-vؕ%Yy|K֭[뮻 2xhۗNKY\´mv~i&5PuaYnj֢(!ry@x뭷VK]׿MqT8B X$XG M`D&NvL.2fffP!/^'Ntgff,6K0(kh8-яO B%E}ֵk.2]zFئL>ܸ߰q'OIDATb1:!_zYKe ~Ua=>zq}i*n޼jN-s̭?_[[XX(eP$ɓal66|^XPvo,,pmM`ff$ guO:ǎZ\\\㨀q ! @S|?={C1{ZųGv:^0v8unsss& e|DPn; & j6?uDZmׅi}(J/|&8fu D8jA$XVpM_xx/`IYg/eѰiZMEQfcEufTda1+T`0IKQȲn ^o^z+wif0I@h?.azkF?ڻumǽ8|x+7cѴ3Ǩ&j6vwwu!˗/;VV?yя %rي3<.WO'x\\.u2+P5&[?6,8nccΝ;Lj=$kD4M+YU*;s$bI41>cXoapرϜ9d\[tPv:t֯] ~l,Ynmm9| N\p0|;EQjZ??|jb7{ KeJ?ϵϢb't3wLŧ}K !/G$Ah`U+8tnxgHLW6sʆ8{ދ,-siF z??L}j54ͷ:ߊx$%3pR˘(ʿ]__yj9Vkg{{/EyQÒ$OHkr]Z׿Ofm k"giiȲ񕕕/ :iaHR&۶(Jj=W_|뵦0UN QIcx@<ۊtyꗿKS~@wM2{ԩkkkT* #(0sFG,z\z^ܜl6)lc_\^/ض/JӧT*w image/svg+xml Scott Kirkwood A key-mon-1.17/setup.py0000640006766500116100000000555312261421461016254 0ustar scottkirkwoodeng00000000000000#!/usr/bin/env python # # Copyright 2010 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from distutils.core import setup import gettext NAME = 'key-mon' DIR = 'src/keymon' gettext.install(NAME, DIR + '/locale') VER = '1.17' PY_NAME = 'key_mon' DEB_NAME = NAME.replace('-', '') RELEASE_FILE = 'RELEASE.rst' VCS = 'http://%s.code.google.com/hg' % NAME PY_SRC = '%s.py' % PY_NAME DEPENDS = ['python-xlib', 'python-gtk2'] DEPENDS_STR = ' '.join(DEPENDS) MENU_SUBSECTION = 'Graphics' AUTHOR_NAME = 'Scott Kirkwood' COPYRIGHT_NAME = 'Google Inc.' GOOGLE_CODE_EMAIL = 'scott@forusers.com' MAILING_LIST = 'key-mon-discuss@googlegroups.com' KEYWORDS = ['keyboard', 'status', 'monitor', 'education'] MAN_FILE = 'man/%s.1' % NAME DESKTOP_FILE = 'icons/%s.desktop' % NAME ICON = 'icons/%s.xpm' % NAME COMMAND = '/usr/bin/%s' % NAME LANGS = ['pt_BR'] HICOLOR_PNG_SIZES = [16, 24, 32, 48, 64, 128] SETUP = dict( name=NAME, version=VER, packages=['keymon'], package_dir={ 'keymon': 'src/keymon'}, package_data = { 'keymon': [ 'themes/**/*', '*.kbd', 'icons/key-mon.desktop', 'locale/**/*/*.mo'], }, data_files = [ ('share/pixmaps', [ICON]), ('share/icons/hicolor', ['icons/hicolor/%dx%d/apps/%s.png' % (x, x, NAME) for x in HICOLOR_PNG_SIZES]), ('share/icons/hicolor', ['icons/hicolor/scalable/apps/%s.svg' % NAME]), ], scripts=['src/key-mon'], author=AUTHOR_NAME, author_email='scott+keymon@forusers.com', platforms=['POSIX'], license='Apache 2.0', keywords=' '.join(KEYWORDS), url='http://code.google.com/p/%s' % NAME, download_url='http://%s.googlecode.com/files/%s-%s.zip' % (NAME, NAME, VER), description=_('A screencast utility that displays your keyboard and mouse status'), long_description=_("""Key-mon is useful for teaching since it shows the current status of your keyboard and mouse and you use them in another application. No longer do you need to say 'Now I'm pressing the Ctrl-D key', your students can just see the keystroke for themselves."""), classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: X11 Applications', 'Intended Audience :: Education', 'License :: OSI Approved :: Apache Software License', 'Operating System :: POSIX :: Linux', 'Topic :: Education :: Computer Aided Instruction (CAI)', ], ) if __name__ == '__main__': setup(**SETUP) key-mon-1.17/INSTALL.rst0000640006766500116100000000172112130344127016371 0ustar scottkirkwoodeng00000000000000================== Installing key-mon ================== Downloading ----------- You will always find the latest version at: http://code.google.com/p/key-mon/downloads/list If you prefer you can clone repository from:: hg clone http://key-mon.code.google.com/hg key-mon Installation ------------ To install using ``pip``,:: $ pip install key-mon To install using ``easy_install``,:: $ easy_install key-mon To install from .deb package:: $ sudo dpkg -i key-mon*.deb If you get errors like Package key-mon depends on XXX; however it is not installed. $ sudo apt-get -f install Should install everything you need, then run: $ sudo dpkg -i key-mon*.deb # again Dependancies ------------ This program requires:: * python-xlib - Interface for Python to the X11 Protocol (http://python-xlib.sourceforge.net/) * python-gtk2 - Python bindings for the GTK+ widget set (http://www.pygtk.org/) -- file generated by `pybdist`.key-mon-1.17/README.pt_BR0000640006766500116100000000172412130344127016421 0ustar scottkirkwoodeng00000000000000Key-mon ======= Um ferramento que mostra as teclas e botões pressionados. Key-mon é útil para ensinar uma curso no computador porque mostra o estado dos teclas e os botões do mouse. Não preciso mais falar 'agora eu esto pressionando a tecla Ctrl-D', os alunos veja eles mesmos. Home Page ========= You can find key-mon hosted at: http://code.google.com/p/key-mon You can file bugs at: http://code.google.com/p/key-mon/issues/list Latest downloads can be found at: http://code.google.com/p/key-mon/downloads/list Requirements ============ This program requires other libraries which you may or may not have installed. * python-xlib - Interface for Python to the X11 Protocol (http://python-xlib.sourceforge.net/) * python-gtk2 - Python bindings for the GTK+ widget set (http://www.pygtk.org/) License ======= Apache 2.0 You can find it in the /home/scottkirkwood/key-mon/LICENSE-2.0.txt file. -- file generated by `pybdist`.