screenkey-0.2/0000755000000000000000000000000011567275623010247 5ustar screenkey-0.2/README0000644000000000000000000000246011405435531011114 0ustar Screenkey v0.2 http://launchpad.net/screenkey About ===== Screencast your keys. A screencast tool to display your keys inspired by Screenflick and initially based on the key-mon project code. Usage ===== Download the lastest version from https://launchpad.net/screenkey/+download To run without installing (change x.x by current version number) tar xvfz screenkey-x.x.tar.gz cd screenkey-x.x/ sudo ./screenkey To install tar xvfz screenkey-x.x.tar.gz cd screenkey-x.x/ sudo ./setup.py install Or you can use dpkg (Debian and Ubuntu) sudo dpkg -i screenkey_x.x-y_all.deb Author ====== Pablo Seminario License ======= Copyright (c) 2010 Pablo Seminario This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . screenkey-0.2/setup.py0000755000000000000000000000141011405435633011746 0ustar #!/usr/bin/env python from distutils.core import setup setup( name = 'screenkey', version = '0.2', packages = ['Screenkey'], package_dir = {'Screenkey': 'Screenkey'}, data_files = [('/usr/share/applications', ['data/screenkey.desktop'])], scripts=['screenkey'], author='Pablo Seminario', author_email='pabluk@gmail.com', platforms=['POSIX'], license='GPLv3', keywords='screencast keyboard keys', url='http://launchpad.net/screenkey', download_url='http://launchpad.net/screenkey/+download', description='A screencast tool to display keys', long_description=""" Screenkey is a useful tool for presentations or screencasts. Inspired by ScreenFlick and initially based on the key-mon project code. """, ) screenkey-0.2/Screenkey/0000755000000000000000000000000011567274174012177 5ustar screenkey-0.2/Screenkey/modmap.py0000644000000000000000000000676211405503744014026 0ustar #!/usr/bin/env python # Copyright (c) 2010 Pablo Seminario # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import re import subprocess def cmd_keymap_table(): return subprocess.Popen( ['xmodmap','-pk'], stdout=subprocess.PIPE).communicate()[0] def cmd_modifier_map(): return subprocess.Popen( ['xmodmap','-pm'], stdout=subprocess.PIPE).communicate()[0] def get_keymap_table(): keymap = {} keymap_table = cmd_keymap_table() re_line = re.compile(r'0x\w+') for line in keymap_table.split('\n')[1:]: if len(line) > 0: keycode = re.search(r'\s+(\d+).*', line) if keycode: new_keysyms = [] keycode = int(keycode.group(1)) keysyms = re_line.findall(line) # When you press only one key unicode_char = '' try: unicode_char = unichr(int(keysyms[0], 16)) except: unicode_char = '' if unicode_char == u'\x00': unicode_char = '' new_keysyms.append(unicode_char) # When you press a key plus Shift key unicode_char = '' try: unicode_char = unichr(int(keysyms[1], 16)) except: unicode_char = '' if unicode_char == u'\x00': unicode_char = '' new_keysyms.append(unicode_char) # When you press a key plus meta (dead keys) unicode_char = '' try: unicode_char = unichr(int(keysyms[4], 16)) except: unicode_char = '' if unicode_char == u'\x00': unicode_char = '' new_keysyms.append(unicode_char) # When you press a key plus meta plus Shift key unicode_char = '' try: unicode_char = unichr(int(keysyms[5], 16)) except: unicode_char = '' if unicode_char == u'\x00': unicode_char = '' new_keysyms.append(unicode_char) #keymap[keycode-8] = new_keysyms keymap[keycode] = new_keysyms return keymap def get_modifier_map(): modifiers = {} modifier_map = cmd_modifier_map() re_line = re.compile(r'(0x\w+)') for line in modifier_map.split('\n')[1:]: if len(line) > 0: mod_name = re.match(r'(\w+).*', line) if mod_name: mod_name = mod_name.group(1) keycodes = re_line.findall(line) # Convert key codes from hex to dec for use them # with the keymap table keycodes =[ int(kc, 16) for kc in keycodes] modifiers[mod_name] = keycodes return modifiers screenkey-0.2/Screenkey/listenkdb.py0000644000000000000000000002124611405503744014522 0ustar # Copyright (c) 2010 Pablo Seminario # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import threading import time import sys import modmap from Xlib import X, XK, display from Xlib.ext import record from Xlib.protocol import rq MODE_RAW = 0 MODE_NORMAL = 1 REPLACE_KEYS = { 'XK_Escape':u'Esc ', 'XK_Tab':u'\u21B9 ', 'XK_Return':u'\u23CE ', 'XK_Space':u' ', 'XK_Caps_Lock':u'Caps ', 'XK_F1':u'F1 ', 'XK_F2':u'F2 ', 'XK_F3':u'F3 ', 'XK_F4':u'F4 ', 'XK_F5':u'F5 ', 'XK_F6':u'F6 ', 'XK_F7':u'F7 ', 'XK_F8':u'F8 ', 'XK_F9':u'F9 ', 'XK_F10':u'F10 ', 'XK_F11':u'F11 ', 'XK_F12':u'F12 ', 'XK_Home':u'Home ', 'XK_Up':u'\u2191', 'XK_Page_Up':u'PgUp ', 'XK_Left':u'\u2190', 'XK_Right':u'\u2192', 'XK_End':u'End ', 'XK_Down':u'\u2193', 'XK_Next':u'PgDn ', 'XK_Insert':u'Ins ', 'XK_Delete':u'Del ', } class ListenKbd(threading.Thread): def __init__(self, label, logger, mode): threading.Thread.__init__(self) self.mode = mode self.logger = logger self.label = label self.text = "" self.command = None self.shift = None self.cmd_keys = { 'shift': False, 'ctrl': False, 'alt': False, 'capslock': False, 'meta': False, 'super':False } self.logger.debug("Thread created") self.keymap = modmap.get_keymap_table() self.modifiers = modmap.get_modifier_map() self.local_dpy = display.Display() self.record_dpy = display.Display() if not self.record_dpy.has_extension("RECORD"): self.logger.error("RECORD extension not found.") print "RECORD extension not found" sys.exit(1) self.ctx = self.record_dpy.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.KeyRelease), 'errors': (0, 0), 'client_started': False, 'client_died': False, }]) def run(self): self.logger.debug("Thread started.") self.record_dpy.record_enable_context(self.ctx, self.key_press) def lookup_keysym(self, keysym): for name in dir(XK): if name[:3] == "XK_" and getattr(XK, name) == keysym: return name[3:] return "" def replace_key(self, key, keysym): for name in dir(XK): if name[:3] == "XK_" and getattr(XK, name) == keysym: if name in REPLACE_KEYS: return REPLACE_KEYS[name] def update_text(self, string=None): if not string is None: self.text = "%s%s" % (self.label.get_text(), string) self.label.set_text(self.text) else: self.label.set_text("") self.label.emit("text-changed") def key_press(self, reply): if reply.category != record.FromServer: return if reply.client_swapped: self.logger.warning( "* received swapped protocol data, cowardly ignored" ) return if not len(reply.data) or ord(reply.data[0]) < 2: # not an event return data = reply.data key = None while len(data): event, data = rq.EventField(None).parse_binary_value(data, self.record_dpy.display, None, None) if event.type in [X.KeyPress, X.KeyRelease]: if self.mode == MODE_NORMAL: key = self.key_normal_mode(event) if self.mode == MODE_RAW: key = self.key_raw_mode(event) if not key: return self.update_text(key) def key_normal_mode(self, event): key = '' mod = '' keysym = self.local_dpy.keycode_to_keysym(event.detail, 0) if event.detail in self.keymap: key_normal, key_shift, key_dead, key_deadshift = \ self.keymap[event.detail] self.logger.debug("Key %s(keycode) %s. Symbols %s" % (event.detail, event.type == X.KeyPress and "pressed" or "released", self.keymap[event.detail]) ) else: self.logger.debug('No mapping for scan_code %d' % event.detail) return # Alt key if event.detail in self.modifiers['mod1']: if event.type == X.KeyPress: self.cmd_keys['alt'] = True else: self.cmd_keys['alt'] = False return # Meta key # Fixme: it must use self.modifiers['mod5'] # but doesn't work if event.detail == 108: if event.type == X.KeyPress: self.cmd_keys['meta'] = True else: self.cmd_keys['meta'] = False return # Super key if event.detail in self.modifiers['mod4']: if event.type == X.KeyPress: self.cmd_keys['super'] = True else: self.cmd_keys['super'] = False return # Ctrl keys elif event.detail in self.modifiers['control']: if event.type == X.KeyPress: self.cmd_keys['ctrl'] = True else: self.cmd_keys['ctrl'] = False return # Shift keys elif event.detail in self.modifiers['shift']: if event.type == X.KeyPress: self.cmd_keys['shift'] = True else: self.cmd_keys['shift'] = False return # Capslock key elif event.detail in self.modifiers['lock']: if event.type == X.KeyPress: if self.cmd_keys['capslock']: self.cmd_keys['capslock'] = False else: self.cmd_keys['capslock'] = True return # Backspace key elif event.detail == 22 and event.type == X.KeyPress: if len(self.label.get_text()) > 0: self.label.set_text( unicode(self.label.get_text(), 'utf-8')[:-1] ) key = "" else: return else: if event.type == X.KeyPress: key = key_normal if self.cmd_keys['ctrl']: mod = mod + "Ctrl+" if self.cmd_keys['alt']: mod = mod + "Alt+" if self.cmd_keys['super']: mod = mod + "Super+" if self.cmd_keys['shift']: key = key_shift if self.cmd_keys['capslock'] \ and ord(key_normal) in range(97,123): key = key_shift if self.cmd_keys['meta']: key = key_dead if self.cmd_keys['shift'] and self.cmd_keys['meta']: key = key_deadshift string = self.replace_key(key, keysym) if string: key = string if mod != '': key = "%s%s " % (mod, key) else: key = "%s%s" % (mod, key) else: return return key def key_raw_mode(self, event): key = '' if event.type == X.KeyPress: keysym = self.local_dpy.keycode_to_keysym(event.detail, 0) key = self.lookup_keysym(keysym) else: return return key def stop(self): self.local_dpy.record_disable_context(self.ctx) self.local_dpy.flush() self.record_dpy.record_free_context(self.ctx) self.logger.debug("Thread stopped.") screenkey-0.2/Screenkey/__init__.py0000644000000000000000000000022111405435652014272 0ustar APP_NAME = 'Screenkey' APP_DESC = 'Screencast your keys' APP_URL = 'http://launchpad.net/screenkey' VERSION = '0.2' AUTHOR = 'Pablo Seminario' screenkey-0.2/Screenkey/screenkey.py0000644000000000000000000003470011405503744014532 0ustar # Copyright (c) 2010 Pablo Seminario # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import pygtk pygtk.require('2.0') import gtk import gobject import glib import pango import pickle from threading import Timer from Screenkey import APP_NAME, APP_DESC, APP_URL, VERSION, AUTHOR from listenkdb import ListenKbd POS_TOP = 0 POS_CENTER = 1 POS_BOTTOM = 2 SIZE_LARGE = 0 SIZE_MEDIUM = 1 SIZE_SMALL = 2 MODE_RAW = 0 MODE_NORMAL = 1 class Screenkey(gtk.Window): POSITIONS = { POS_TOP:'Top', POS_CENTER:'Center', POS_BOTTOM:'Bottom', } SIZES = { SIZE_LARGE: 'Large', SIZE_MEDIUM: 'Medium', SIZE_SMALL: 'Small', } MODES = { MODE_RAW:'Raw', MODE_NORMAL:'Normal', } STATE_FILE = os.path.join(glib.get_user_cache_dir(), 'screenkey.dat') def __init__(self, logger, nodetach): gtk.Window.__init__(self) self.timer = None self.logger = logger self.options = self.load_state() if not self.options: self.options = { 'timeout': 2.5, 'position': POS_BOTTOM, 'size': SIZE_MEDIUM, 'mode': MODE_NORMAL, } if not nodetach: self.logger.debug("Detach from the parent.") self.drop_tty() self.set_skip_taskbar_hint(True) self.set_skip_pager_hint(True) self.set_keep_above(True) self.set_decorated(False) self.stick() self.set_property('accept-focus', False) self.set_property('focus-on-map', False) self.set_position(gtk.WIN_POS_CENTER) bgcolor = gtk.gdk.color_parse("black") self.modify_bg(gtk.STATE_NORMAL, bgcolor) self.set_opacity(0.7) gobject.signal_new("text-changed", gtk.Label, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()) self.label = gtk.Label() self.label.set_justify(gtk.JUSTIFY_RIGHT) self.label.set_ellipsize(pango.ELLIPSIZE_START) self.label.connect("text-changed", self.on_label_change) self.label.show() self.add(self.label) self.screen_width = gtk.gdk.screen_width() self.screen_height = gtk.gdk.screen_height() self.set_window_size(self.options['size']) self.set_gravity(gtk.gdk.GRAVITY_CENTER) self.set_xy_position(self.options['position']) self.listenkbd = ListenKbd(self.label, logger=self.logger, mode=self.options['mode']) self.listenkbd.start() menu = gtk.Menu() show_item = gtk.CheckMenuItem("Show keys") show_item.set_active(True) show_item.connect("toggled", self.on_show_keys) show_item.show() menu.append(show_item) preferences_item = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES) preferences_item.connect("activate", self.on_preferences_dialog) preferences_item.show() menu.append(preferences_item) about_item = gtk.ImageMenuItem(gtk.STOCK_ABOUT) about_item.connect("activate", self.on_about_dialog) about_item.show() menu.append(about_item) separator_item = gtk.SeparatorMenuItem() separator_item.show() menu.append(separator_item) image = gtk.ImageMenuItem(gtk.STOCK_QUIT) image.connect("activate", self.quit) image.show() menu.append(image) menu.show() try: import appindicator self.systray = appindicator.Indicator(APP_NAME, 'indicator-messages', appindicator.CATEGORY_APPLICATION_STATUS) self.systray.set_status (appindicator.STATUS_ACTIVE) self.systray.set_attention_icon ("indicator-messages-new") self.systray.set_icon( "preferences-desktop-keyboard-shortcuts") self.systray.set_menu(menu) self.logger.debug("Using AppIndicator.") except(ImportError): self.systray = gtk.StatusIcon() self.systray.set_from_icon_name( "preferences-desktop-keyboard-shortcuts") self.systray.connect("popup-menu", self.on_statusicon_popup, menu) self.logger.debug("Using StatusIcon.") self.connect("delete-event", self.quit) def quit(self, widget, data=None): self.listenkbd.stop() gtk.main_quit() def load_state(self): """Load stored options""" options = None try: f = open(self.STATE_FILE, 'r') try: options = pickle.load(f) self.logger.debug("Options loaded.") except: f.close() except IOError: self.logger.debug("file %s does not exists." % self.STATE_FILE) return options def store_state(self, options): """Store options""" try: f = open(self.STATE_FILE, 'w') try: pickle.dump(options, f) self.logger.debug("Options saved.") except: f.close() except IOError: self.logger.debug("Cannot open %s." % self.STATE_FILE) def set_window_size(self, setting): """Set window and label size.""" window_width = self.screen_width window_height = -1 if setting == SIZE_LARGE: window_height = 24 * self.screen_height / 100 if setting == SIZE_MEDIUM: window_height = 12 * self.screen_height / 100 if setting == SIZE_SMALL: window_height = 8 * self.screen_height / 100 attr = pango.AttrList() attr.change(pango.AttrSize(( 50 * window_height / 100) * 1000, 0, -1)) attr.change(pango.AttrFamily("Sans", 0, -1)) attr.change(pango.AttrWeight(pango.WEIGHT_BOLD, 0, -1)) attr.change(pango.AttrForeground(65535, 65535, 65535, 0, -1)) self.label.set_attributes(attr) self.resize(window_width, window_height) def set_xy_position(self, setting): """Set window position.""" window_width, window_height = self.get_size() if setting == POS_TOP: self.move(0, window_height * 2) if setting == POS_CENTER: self.move(0, self.screen_height / 2) if setting == POS_BOTTOM: self.move(0, self.screen_height - window_height * 2) def on_statusicon_popup(self, widget, button, timestamp, data=None): if button == 3: if data: data.show() data.popup(None, None, gtk.status_icon_position_menu, 3, timestamp, widget) def on_label_change(self, widget, data=None): if not self.get_property('visible'): gtk.gdk.threads_enter() self.set_xy_position(self.options['position']) self.stick() self.show() gtk.gdk.threads_leave() if self.timer: self.timer.cancel() self.timer = Timer(self.options['timeout'], self.on_timeout) self.timer.start() def on_timeout(self): self.hide() self.label.set_text("") def on_change_mode(self, mode): self.listenkbd.stop() self.listenkbd = ListenKbd(self.label, logger=self.logger, mode=mode) self.listenkbd.start() def on_show_keys(self, widget, data=None): if widget.get_active(): self.logger.debug("Screenkey enabled.") self.listenkbd = ListenKbd(self.label, logger=self.logger, mode=self.options['mode']) self.listenkbd.start() else: self.logger.debug("Screenkey disabled.") self.listenkbd.stop() def on_preferences_dialog(self, widget, data=None): prefs = gtk.Dialog(APP_NAME, None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)) def on_sb_time_changed(widget, data=None): self.options['timeout'] = widget.get_value() self.logger.debug("Timeout value changed.") def on_cbox_sizes_changed(widget, data=None): index = widget.get_active() if index >= 0: self.options['size'] = index self.set_window_size(self.options['size']) self.logger.debug("Window size changed.") def on_cbox_modes_changed(widget, data=None): index = widget.get_active() if index >= 0: self.options['mode'] = index self.on_change_mode(self.options['mode']) self.logger.debug("Key mode changed.") def on_cbox_changed(widget, data=None): index = widget.get_active() name = widget.get_name() if index >= 0: self.options[name] = index self.logger.debug("Window position changed.") frm_main = gtk.Frame("Preferences") frm_main.set_border_width(6) vbox_main = gtk.VBox() frm_time = gtk.Frame("Time") frm_time.set_border_width(4) frm_time.get_label_widget().set_use_markup(True) frm_time.set_shadow_type(gtk.SHADOW_NONE) hbox_time = gtk.HBox() lbl_time1 = gtk.Label("Display for") lbl_time2 = gtk.Label("seconds") sb_time = gtk.SpinButton(digits=1) sb_time.set_increments(0.5, 1.0) sb_time.set_range(0.5, 10.0) sb_time.set_numeric(True) sb_time.set_update_policy(gtk.UPDATE_IF_VALID) sb_time.set_value(self.options['timeout']) sb_time.connect("value-changed", on_sb_time_changed) hbox_time.pack_start(lbl_time1, expand=False, fill=False, padding=6) hbox_time.pack_start(sb_time, expand=False, fill=False, padding=4) hbox_time.pack_start(lbl_time2, expand=False, fill=False, padding=4) frm_time.add(hbox_time) frm_time.show_all() frm_aspect = gtk.Frame("Aspect") frm_aspect.set_border_width(4) frm_aspect.get_label_widget().set_use_markup(True) frm_aspect.set_shadow_type(gtk.SHADOW_NONE) vbox_aspect = gtk.VBox(spacing=6) hbox1_aspect = gtk.HBox() lbl_positions = gtk.Label("Position") cbox_positions = gtk.combo_box_new_text() cbox_positions.set_name('position') for key, value in self.POSITIONS.items(): cbox_positions.insert_text(key, value) cbox_positions.set_active(self.options['position']) cbox_positions.connect("changed", on_cbox_changed) hbox1_aspect.pack_start(lbl_positions, expand=False, fill=False, padding=6) hbox1_aspect.pack_start(cbox_positions, expand=False, fill=False, padding=4) hbox2_aspect = gtk.HBox() lbl_sizes = gtk.Label("Size") cbox_sizes = gtk.combo_box_new_text() cbox_sizes.set_name('size') for key, value in self.SIZES.items(): cbox_sizes.insert_text(key, value) cbox_sizes.set_active(self.options['size']) cbox_sizes.connect("changed", on_cbox_sizes_changed) hbox2_aspect.pack_start(lbl_sizes, expand=False, fill=False, padding=6) hbox2_aspect.pack_start(cbox_sizes, expand=False, fill=False, padding=4) vbox_aspect.pack_start(hbox1_aspect) vbox_aspect.pack_start(hbox2_aspect) frm_aspect.add(vbox_aspect) frm_kbd = gtk.Frame("Keys") frm_kbd.set_border_width(4) frm_kbd.get_label_widget().set_use_markup(True) frm_kbd.set_shadow_type(gtk.SHADOW_NONE) hbox_kbd = gtk.HBox() lbl_kbd = gtk.Label("Mode") cbox_modes = gtk.combo_box_new_text() cbox_modes.set_name('mode') for key, value in self.MODES.items(): cbox_modes.insert_text(key, value) cbox_modes.set_active(self.options['mode']) cbox_modes.connect("changed", on_cbox_modes_changed) hbox_kbd.pack_start(lbl_kbd, expand=False, fill=False, padding=6) hbox_kbd.pack_start(cbox_modes, expand=False, fill=False, padding=4) frm_kbd.add(hbox_kbd) vbox_main.pack_start(frm_time, False, False, 6) vbox_main.pack_start(frm_aspect, False, False, 6) vbox_main.pack_start(frm_kbd, False, False, 6) frm_main.add(vbox_main) prefs.vbox.pack_start(frm_main) prefs.set_destroy_with_parent(True) prefs.set_resizable(False) prefs.set_has_separator(False) prefs.set_default_response(gtk.RESPONSE_CLOSE) prefs.vbox.show_all() gtk.gdk.threads_enter() response = prefs.run() if response: self.store_state(self.options) gtk.gdk.threads_leave() prefs.destroy() def on_about_dialog(self, widget, data=None): about = gtk.AboutDialog() about.set_program_name(APP_NAME) about.set_version(VERSION) about.set_copyright(u"2010 \u00a9 %s" % AUTHOR) about.set_comments(APP_DESC) about.set_documenters( [u"Jos\xe9 Mar\xeda Quiroga "] ) about.set_website(APP_URL) about.set_icon_name('preferences-desktop-keyboard-shortcuts') about.set_logo_icon_name( 'preferences-desktop-keyboard-shortcuts' ) gtk.gdk.threads_enter() about.run() gtk.gdk.threads_leave() about.destroy() def drop_tty(self): # We fork and setsid so that we drop the controlling # tty. if os.fork() != 0: os._exit(0) os.setsid() screenkey-0.2/LICENSE0000644000000000000000000000123311405434703011236 0ustar Copyright (c) 2010 Pablo Seminario This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . screenkey-0.2/screenkey0000755000000000000000000000412311405503744012152 0ustar #!/usr/bin/env python # Copyright (c) 2010 Pablo Seminario # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import logging from optparse import OptionParser import pygtk pygtk.require('2.0') import gtk from Screenkey import APP_NAME, APP_DESC, VERSION from Screenkey.screenkey import Screenkey gtk.gdk.threads_init() def Main(): parser = OptionParser(description=APP_DESC, version=VERSION) parser.add_option("--no-detach", action="store_true", dest="nodetach", default=False, help="do not detach from the parent") parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False, help="show debug information") (options, args) = parser.parse_args() if options.debug: if options.nodetach: # Send debug messages to standard output logfile = None else: logfile = os.path.join(os.path.expanduser('~'), '.screenkey.log') username = os.environ.get('SUDO_USER') if username: homedir = os.path.expanduser('~%s' % username) if homedir != '~%s' % username: logfile = os.path.join(homedir, '.screenkey.log') logging.basicConfig(filename=logfile, level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) logger = logging.getLogger(APP_NAME) s = Screenkey(logger=logger, nodetach=options.nodetach) gtk.main() if __name__ == "__main__": Main() screenkey-0.2/data/0000755000000000000000000000000011405614620011141 5ustar screenkey-0.2/data/screenkey.desktop0000644000000000000000000000031311405435560014525 0ustar [Desktop Entry] Encoding=UTF-8 Name=Screenkey Comment=Screencast your keys Version=0.2 Exec=screenkey Terminal=false Icon=preferences-desktop-keyboard-shortcuts Type=Application Categories=GNOME;Utility screenkey-0.2/PKG-INFO0000644000000000000000000000076111405614620011331 0ustar Metadata-Version: 1.0 Name: screenkey Version: 0.2 Summary: A screencast tool to display keys Home-page: http://launchpad.net/screenkey Author: Pablo Seminario Author-email: pabluk@gmail.com License: GPLv3 Download-URL: http://launchpad.net/screenkey/+download Description: Screenkey is a useful tool for presentations or screencasts. Inspired by ScreenFlick and initially based on the key-mon project code. Keywords: screencast keyboard keys Platform: POSIX screenkey-0.2/debian/0000755000000000000000000000000011567275623011471 5ustar screenkey-0.2/debian/copyright0000644000000000000000000000327411405615067013421 0ustar This work was packaged for Debian by: Pablo Seminario on Mon, 14 Jun 2010 16:34:58 +0200 It was downloaded from: http://launchpad.net/screenkey Upstream Author(s): Pablo Seminario Copyright: License: This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU General Public License version 3 can be found in `/usr/share/common-licenses/GPL-3'. The Debian packaging is: Copyright (C) 2010 Pablo Seminario # Please chose a license for your packaging work. If the program you package # uses a mainstream license, using the same license is the safest choice. # Please avoid to pick license terms that are more restrictive than the # packaged work, as it may make Debian's contributions unacceptable upstream. # If you just want it to be GPL version 3, leave the following line in. and is licensed under the GPL version 3, see above. # Please also look if there are files or directories which have a # different copyright/license attached and list them here. screenkey-0.2/debian/changelog0000644000000000000000000000020011405615067013322 0ustar screenkey (0.2) unstable; urgency=low * Release 0.2 -- Pablo Seminario Mon, 14 Jun 2010 18:18:58 +0200 screenkey-0.2/debian/control0000644000000000000000000000067611405615067013074 0ustar Source: screenkey Section: utils Priority: extra Maintainer: Pablo Seminario Build-Depends: debhelper (>= 7), cdbs Standards-Version: 3.8.3 Homepage: http://launchpad.net/screenkey Package: screenkey Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends}, python (>= 2.5), python-gtk2, python-xlib Description: Screencast your keys A screencast tool inspired by Screenflick and initially based on the key-mon project. screenkey-0.2/debian/docs0000644000000000000000000000001711405615067012331 0ustar README LICENSE screenkey-0.2/debian/compat0000644000000000000000000000000211405615067012656 0ustar 7 screenkey-0.2/debian/rules0000755000000000000000000000110611405615067012536 0ustar #!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 #include /usr/share/cdbs/1/rules/debhelper.mk #binary-install/screenkey:: # dh_icons #binary-fixup/screenkey:: # dh_gconf --priority=16 %: dh $@