--- /dev/null
+#!/usr/bin/env python
+
+# Copyright (C) 2011-2012 Neil Brown <neilb@suse.de>
+#
+# 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 2 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Connect 'tapboard' with 'fakeinput' to make a working on-screen
+# keyboard.
+# This script uses a long press on the 'power' button to raise
+# the keyboard, and also a double-tap on the 'z' axis of the
+# accelerometer. However that requires a kernel driver that I
+# never published, so it won't work at the moment.
+
+import time, gtk
+from fakeinput import fakeinput
+from tapboard import TapBoard
+from evdev import EvDev
+import gobject
+
+class KeyboardIcon(gtk.StatusIcon):
+ def __init__(self, activate = None):
+ gtk.StatusIcon.__init__(self)
+ self.set_from_file('/usr/local/pixmaps/tapinput.png')
+ self.set_activate(activate)
+
+ def set_activate(self, activate):
+ if activate:
+ self.connect('activate', activate)
+
+power_timer = None
+def power_pressed(cnt, type, code, value, win):
+ if type != 1:
+ # not a key press
+ return
+ if code != 116:
+ # not the power key
+ return
+ global power_timer
+ if value != 1:
+ # not a down press
+ if power_timer != None:
+ gobject.source_remove(power_timer)
+ power_timer = None
+ return
+ power_timer = gobject.timeout_add(300, power_held, win)
+
+def power_held(win):
+ global power_timer
+ power_timer = None
+ if win.visible:
+ win.hide()
+ win.visible = False
+ else:
+ win.hide()
+ win.show()
+ win.activate()
+ win.visible = True
+ return False
+
+last_tap = 0
+def tap_pressed(cnt, type, code, value, win):
+ global last_tap
+ if type != 1:
+ # not a key press
+ return
+ if code != 309:
+ # not BtnZ
+ return
+ if value != 1:
+ # only want dow, not up
+ return
+ now = time.time()
+ print now, last_tap
+ if now - last_tap < 0.2:
+ # two taps
+ if win.visible:
+ win.hide()
+ win.visible = False
+ else:
+ win.hide()
+ win.show()
+ win.activate()
+ win.visible = True
+ last_tap = 0
+ else:
+ last_tap = now
+
+ico = KeyboardIcon()
+w = gtk.Window(type=gtk.WINDOW_POPUP)
+w.visible = True
+w.connect("destroy", lambda w: gtk.main_quit())
+ti = TapBoard()
+w.add(ti)
+w.set_default_size(ti.width, ti.height)
+root = gtk.gdk.get_default_root_window()
+(x,y,width,height,depth) = root.get_geometry()
+x = int((width - ti.width)/2)
+y = int((height - ti.height)/2)
+w.move(x,y)
+def activate(ignore):
+ w.hide()
+ w.show()
+ w.visible = True
+ w.activate()
+ w.move(x,y)
+ico.set_activate(activate)
+fi = fakeinput()
+def dokey(ti, str):
+ fi.send_char(str)
+ti.connect('key', dokey)
+def domove(ti, x,y):
+ global startx, starty
+ if x == 0 and y == 0:
+ (startx, starty) = w.get_position()
+ x = 0
+ w.move(startx+x, starty+y)
+
+ti.connect('move', domove)
+def hideme(ti):
+ w.hide()
+ w.visible = False
+ti.connect('hideme', hideme)
+try:
+ pbtn = EvDev("/dev/input/power", power_pressed, w)
+ tbtn = EvDev("/dev/input/accel", tap_pressed, w)
+except:
+ pass
+ti.show()
+w.show()
+fi.new_window()
+gtk.main()
+