Ehkä se on paras jos postaan tämän koko koodin tähän, niin voit katsoa siitä suoraan. Huomaa ainakin, että rivillä 68 from evdevDas import Device omassa koodissani luetaan DAS-näppäimistönasettelu, joten siinä kohdassa valitse pelkkä from evdev import....
#!/usr/bin/env python
"""
GTK+ Key Status Monitor
Monitor the status of your mouse buttons and the alt/ctrl/shift keys
Jiri Hnidek added support for other keys
This program requires the Linux input event system to be loaded, and
requires keyboard and mouse event devices. Please specify the location
of the devices on your system below:
"""
# Device locations
#KEYBOARD_LOCATION = "/dev/input/event0"
#MOUSE_LOCATION = "/dev/input/event1"
KEYBOARD_LOCATION = "/dev/input/by-id/usb-_USB_Keyboard-event-kbd"
MOUSE_LOCATION = "/dev/input/by-id/usb-0461_USB_Optical_Mouse-event-mouse"
#Window width and height
WIDTH= 328
HEIGHT= 48
# Update speed (how fast the interface is updated, in milliseconds)
UPDATE_SPEED = 20
# Delay of displaying key-status, total_delay = DELAY * UPDATE_SPEED [ms]
DELAY = 50 # 7
DELAY_SPECIAL = 50 # 3
DELAY_MOUSE = 50 # 5
"""
Copyright (C) 2005 Daniel G. Taylor <danielgtaylor at gmail dot com>
Copyright (C) 2005 Jiri Hnidek <jiri dot hnidek at vslib cz>
Icons were created by
Copyright (C) 2005 Jakub (jimmac) Steiner <jakub at ximian dot com>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Release History:
- Version 1: 12 January 2005
- Initial release.
- Version 2: 13 March 2005
- Added support for other keys and some other tweaking
- Version 3: 13 March 2005
- Added support for key-status delay, it is useful for
video capturing
"""
import gtk, gobject
from sys import argv, exit
from evdevDas import Device # Special thanks to Micah Dowty
import time
import datetime
key_images = {
#"KEY_RESERVED":"./png/null.png",
"KEY_ESC":"./png/Esc.png",
"KEY_1":"./png/1.png",
"KEY_2":"./png/2.png",
"KEY_3":"./png/3.png",
"KEY_4":"./png/4.png",
"KEY_5":"./png/5.png",
"KEY_6":"./png/6.png",
"KEY_7":"./png/7.png",
"KEY_8":"./png/8.png",
"KEY_9":"./png/9.png",
"KEY_0":"./png/0.png",
"KEY_MINUS":"./png/dash.png",
"KEY_EQUAL":"./png/equal.png",
"KEY_BACKSPACE":"./png/backspace.png",
"KEY_TAB":"./png/Tab.png",
"KEY_Q":"./png/q.png",
"KEY_W":"./png/w.png",
"KEY_E":"./png/e.png",
"KEY_R":"./png/r.png",
"KEY_T":"./png/t.png",
"KEY_Y":"./png/y.png",
"KEY_U":"./png/u.png",
"KEY_I":"./png/i.png",
"KEY_O":"./png/o.png",
"KEY_P":"./png/p.png",
"KEY_LEFTBRACE":"./png/squarebracket-left.png",
"KEY_RIGHTBRACE":"./png/squarebracket-right.png",
"KEY_ENTER":"./png/enter.png",
"KEY_A":"./png/a.png",
"KEY_S":"./png/s.png",
"KEY_D":"./png/d.png",
"KEY_F":"./png/f.png",
"KEY_G":"./png/g.png",
"KEY_H":"./png/h.png",
"KEY_J":"./png/j.png",
"KEY_K":"./png/k.png",
"KEY_L":"./png/l.png",
"KEY_SEMICOLON":"./png/semicolon.png",
"KEY_APOSTROPHE":"./png/apostrophe.png",
"KEY_GRAVE":"./png/backquote.png",
"KEY_BACKSLASH":"./png/backslash.png",
"KEY_Z":"./png/z.png",
"KEY_X":"./png/x.png",
"KEY_C":"./png/c.png",
"KEY_V":"./png/v.png",
"KEY_B":"./png/b.png",
"KEY_N":"./png/n.png",
"KEY_M":"./png/m.png",
"KEY_ARING": "./png/aring.png",
"KEY_ADIAERESIS":"./png/adiaeresis.png",
"KEY_ODIAERESIS": "./png/odiaeresis.png",
"KEY_COMMA":"./png/comma.png",
"KEY_DOT":"./png/dot.png",
"KEY_SLASH":"./png/slash.png",
"KEY_KPASTERISK":"./png/kp_asterix.png",
"KEY_SPACE":"./png/spacebar.png",
"KEY_CAPSLOCK":"./png/capslock.png",
"KEY_F1":"./png/F1.png",
"KEY_F2":"./png/F2.png",
"KEY_F3":"./png/F3.png",
"KEY_F4":"./png/F4.png",
"KEY_F5":"./png/F5.png",
"KEY_F6":"./png/F6.png",
"KEY_F7":"./png/F7.png",
"KEY_F8":"./png/F8.png",
"KEY_F9":"./png/F9.png",
"KEY_F10":"./png/F10.png",
"KEY_NUMLOCK":"./png/numlock.png",
#"KEY_SCROLLLOCK":"./png/null.png",
"KEY_KP7":"./png/kp_7.png",
"KEY_KP8":"./png/kp_8.png",
"KEY_KP9":"./png/kp_9.png",
"KEY_KPMINUS":"./png/kp_minus.png",
"KEY_KP4":"./png/kp_4.png",
"KEY_KP5":"./png/kp_5.png",
"KEY_KP6":"./png/kp_6.png",
"KEY_KPPLUS":"./png/kp_plus.png",
"KEY_KP1":"./png/kp_1.png",
"KEY_KP2":"./png/kp_2.png",
"KEY_KP3":"./png/kp_3.png",
"KEY_KP0":"./png/kp_0.png",
"KEY_KPDOT":"./png/kp_dot.png",
#"KEY_103RD":"./png/null.png",
#"KEY_102ND":"./png/null.png",
"KEY_F11":"./png/F11.png",
"KEY_F12":"./png/F12.png",
"KEY_KPENTER":"./png/kp_enter.png",
"KEY_KPSLASH":"./png/kp_slash.png",
#"KEY_SYSRQ":"./png/null.png",
#"KEY_LINEFEED":"./png/null.png",
"KEY_HOME":"./png/home.png",
"KEY_UP":"./png/up.png",
"KEY_PAGEUP":"./png/pageup.png",
"KEY_LEFT":"./png/left.png",
"KEY_RIGHT":"./png/right.png",
"KEY_END":"./png/end.png",
"KEY_DOWN":"./png/down.png",
"KEY_PAGEDOWN":"./png/pagedown.png",
"KEY_INSERT":"./png/insert.png",
"KEY_DELETE":"./png/del.png",
#"KEY_MACRO":"./png/null.png",
#"KEY_MUTE":"./png/null.png",
#"KEY_VOLUMEDOWN":"./png/null.png",
#"KEY_VOLUMEUP":"./png/null.png",
#"KEY_POWER":"./png/null.png",
#"KEY_KPEQUAL":"./png/null.png",
#"KEY_KPPLUSMINUS":"./png/null.png",
"KEY_LEFTMETA":"./png/penguin.png", # windows button
#"KEY_RIGHTMETA":"./png/win_right.png", # windows button
#"KEY_COMPOSE":"./png/win_menu.png", # windows menu button
"KEY_PAUSE":"./png/pause.png"
}
CtrlImages = ("./png/ctrl-null.png", "./png/ctrl.png")
AltImages = ("./png/alt-null.png", "./png/alt.png")
ShiftImages = ("./png/shift-null.png", "./png/shift.png")
class Image(gtk.Image):
""" Holds an image that can switch between two states """
def __init__(self, normal, activated):
gtk.Image.__init__(self)
self.set_from_file(normal)
self.normal = normal
self.activated = activated
self.status = 0
self.delay = -1
def switch(self, key):
""" Switch states """
self.status = key
if key != "null":
self.set_from_file(self.activated)
else:
self.delay = DELAY_SPECIAL
def isPressed(self):
return self.status != 0 and self.status != "null"
def key_hide(self):
self.set_from_file(self.normal)
self.delay = - 1
class KeyImage(gtk.Image):
""" Holds an image that can switch between 105 states """
def __init__(self):
gtk.Image.__init__(self)
self.set_from_file("./png/null.png")
self.hide()
self.delay = -1
self.images = {}
for code_key in key_images.keys():
self.images[code_key] = key_images[code_key]
self.status = 0
def switch(self, key):
""" Switch states """
self.status = key
if key != "null":
self.set_from_file(key_images[key])
self.show()
else:
self.delay = DELAY
def key_hide(self):
self.hide()
self.delay = -1
class MouseImage(gtk.Image):
""" Holds an image that can switch between four mouse states """
def __init__(self, normal, left, middle, right):
gtk.Image.__init__(self)
self.set_from_file(normal)
self.images = {"normal": normal,
"BTN_LEFT": left,
"BTN_MIDDLE": middle,
"BTN_RIGHT": right}
self.status = "normal"
self.toggleRight = 0
self.toggleLeft = 0
self.delay = -1
def switch(self, status):
""" Switch to the new status, either 'BTN_LEFT' 'BTN_MIDDLE' or 'BTN_RIGHT' """
self.status = status
self.set_from_file(self.images[status])
def set_normal(self):
self.status = "normal"
self.set_from_file(self.images["normal"])
self.delay = -1
def setToggle(self, btnDict): # oma
if btnDict.has_key("BTN_LEFT"):
self.toggleLeft = btnDict["BTN_LEFT"]
if btnDict.has_key("BTN_RIGHT"):
self.toggleRight = btnDict["BTN_RIGHT"]
def areBothPressed(self): #oma
#print "LMB = %i" % self.toggleLeft
#print "RMB = %i" % self.toggleRight
#print 20*"="
return (self.toggleLeft==1) and (self.toggleRight==1)
class KeyStatusApp:
def __init__(self, decorated=True, logging="none"):
# setup devices
self.logging = logging
self.logLastKeys = {1:"", 2:"", 3:"", 4:"", 5:"",6:"", 7:""}
try:
self.kb = Device(KEYBOARD_LOCATION) #keyboard
self.ms = Device(MOUSE_LOCATION) #mouse
except OSError, value:
# show a dialog with the error
dialog = gtk.Dialog("Error!", buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
dialog.vbox.pack_start(gtk.Label("There was an error:\n\n" + str(value)))
dialog.show_all()
dialog.run()
exit(1)
# setup GUI
self.window = gtk.Window()
self.window.set_title("KeyStatus")
self.window.set_default_size(WIDTH, HEIGHT)
self.window.set_resizable(True)
self.window.set_geometry_hints(None, WIDTH, HEIGHT, WIDTH, HEIGHT, WIDTH, HEIGHT, -1, -1, -1.0, -1.0)
try:
if not decorated:
self.window.set_decorated(False)
except:
print "AttributeError: 'gtk.Window' object has no attribute 'set_decorated'"
try:
self.window.set_keep_above(True)
except:
print "AttributeError: 'gtk.Window' object has no attribute 'set_keep_above'"
self.mouse = MouseImage("./png/mouse.png", "./png/mouse-left.png",
"./png/mouse-middle.png", "./png/mouse-right.png")
#self.ctrl = Image("./png/ctrl-null.png", "./png/ctrl.png")
#self.alt = Image("./png/alt-null.png", "./png/alt.png")
#self.shift = Image("./png/shift-null.png", "./png/shift.png")
self.ctrl = Image(CtrlImages[0], CtrlImages[1])
self.alt = Image(AltImages[0], AltImages[1])
self.shift = Image(ShiftImages[0], ShiftImages[1])
self.key = KeyImage()
hbox1 = gtk.HBox(False, 0)
hbox1.pack_start(self.mouse, False, True, 0)
hbox1.pack_start(self.ctrl, False, True, 0)
hbox1.pack_start(self.alt, False, True, 0)
hbox1.pack_start(self.shift, False, True, 0)
hbox2 = gtk.HBox(False, 0)
hbox2.pack_start(self.key, False, False, 0)
hbox = gtk.HBox(False, 0)
hbox.pack_start(hbox1)
hbox.pack_start(hbox2)
self.window.add(hbox)
self.window.show_all()
# setup events
self.window.connect("destroy", self.destroy)
gobject.timeout_add(UPDATE_SPEED, self.update)
(self.msx, self.msy) = (0,0)# oma
(self.msxt, self.msyt) = (0,0) # oma
self.i = 1
def destroy(self, widget, data=None):
gtk.main_quit()
def on_window_clicked():
print "click"
def printToLog(self, ctrlStatus, altStatus, shiftStatus, keystring):
timestr= time.strftime("%Y-%m-%d %H:%M:%S")
tuloste = "%s %s%s%s%s" % (timestr, ctrlStatus*"Ctrl-", altStatus*"Alt-", shiftStatus*"Shift-", keystring)
# html-alternative:
kuva_alkaa = "<img src=\""
kuva_loppuu = "\">"
CtrlImage1 = kuva_alkaa + CtrlImages[1] + kuva_loppuu
AltImage1 = kuva_alkaa + AltImages[1] + kuva_loppuu
ShiftImage1 = kuva_alkaa + ShiftImages[1] + kuva_loppuu
html_tuloste = ""
if keystring in key_images:
kuvaImage1 = kuva_alkaa + key_images[keystring] + kuva_loppuu
html_tuloste = "<!-- %s --> %s%s%s%s " % (timestr, ctrlStatus*CtrlImage1, altStatus*AltImage1, shiftStatus*ShiftImage1, kuvaImage1)
if not (tuloste in self.logLastKeys.values()):
if self.logging == "loggingtxt":
# txt-logging
print tuloste
if self.logging == "logginghtml":
# html-alternative:
print html_tuloste
# dump fifo:
self.logLastKeys[7] = self.logLastKeys[6]
self.logLastKeys[6] = self.logLastKeys[5]
self.logLastKeys[5] = self.logLastKeys[4]
self.logLastKeys[4] = self.logLastKeys[3]
self.logLastKeys[3] = self.logLastKeys[2]
self.logLastKeys[2] = self.logLastKeys[1]
self.logLastKeys[1] = tuloste
def update(self):
""" Update the GUI with new event data from the keyboard and mouse devices """
self.ms.buttons = {}
self.kb.poll()
self.ms.poll()
# print self.kb.buttons # debug ... it prints internal button names
key_num = len(self.kb.buttons)
if key_num > 0:
# The keyboard key status is 1 when pressed, 2 when held, and 0 otherwise
# Special keys status
for key in ["KEY_LEFTCTRL", "KEY_RIGHTCTRL"]:
if key in self.kb.buttons:
key_num = key_num - 1
if self.kb.buttons[key] and self.ctrl.status != key:
self.ctrl.switch(key)
elif self.kb.buttons[key] == 0 and self.ctrl.status == key:
self.ctrl.switch("null")
for key in ["KEY_LEFTALT", "KEY_RIGHTALT"]:
if key in self.kb.buttons:
key_num = key_num - 1
if self.kb.buttons[key] and self.alt.status != key:
self.alt.switch(key)
elif self.kb.buttons[key] == 0 and self.alt.status == key:
self.alt.switch("null")
for key in ["KEY_LEFTSHIFT", "KEY_RIGHTSHIFT"]:
if key in self.kb.buttons:
key_num = key_num - 1
if self.kb.buttons[key] and self.shift.status != key:
self.shift.switch(key)
elif self.kb.buttons[key] == 0 and self.shift.status == key:
self.shift.switch("null")
# Other keys status
if(key_num > 0):
for key in key_images.keys():
if key in self.kb.buttons:
if self.kb.buttons[key] and self.key.status != key:
self.key.switch(key)
if self.logging != "none":
self.printToLog(self.ctrl.isPressed(), self.alt.isPressed(), self.shift.isPressed(), key)
elif self.kb.buttons[key] == 0 and self.key.status == key:
self.key.switch("null")
# Delay business for special keys
if self.ctrl.delay > 0:
self.ctrl.delay = self.ctrl.delay - 1
else:
if self.ctrl.delay != -1:
self.ctrl.key_hide()
if self.alt.delay > 0:
self.alt.delay = self.alt.delay - 1
else:
if self.alt.delay != -1:
self.alt.key_hide()
if self.shift.delay > 0:
self.shift.delay = self.shift.delay - 1
else:
if self.shift.delay != -1:
self.shift.key_hide()
# Delay business for common keys
if self.key.delay > 0:
self.key.delay = self.key.delay - 1
else:
if self.key.delay != -1:
self.key.key_hide()
#print self.ms.buttons #
if len(self.ms.buttons) > 0:
self.mouse.setToggle(self.ms.buttons)
# The mouse button status
for button in ["BTN_LEFT", "BTN_MIDDLE", "BTN_RIGHT"]:
if button in self.ms.buttons:
# Blender MMB = LMB + RMB
if self.ms.buttons[button] and self.mouse.status != button:
if self.mouse.areBothPressed(): button = "BTN_MIDDLE"
self.mouse.switch(button)
#print self.mouse.isBothPressed()
#print self.ms.buttons
elif self.ms.buttons[button] == 0 and self.mouse.status != "normal":
self.mouse.delay = DELAY_MOUSE
# Delay business for mouse buttons
if self.mouse.delay > 0:
self.mouse.delay = self.mouse.delay - 1
else:
if self.mouse.delay != -1:
self.mouse.set_normal()
return True
if __name__ == "__main__":
# Create a new instance of our application
decorated = True
logging = "none"
if len(argv) > 1:
for argument in argv:
if argument == "--no-decorations" or argument == "-d":
decorated = False
if argument == "--logging-txt" or argument == "-lt":
logging = "loggingtxt"
if argument == "--logging-html" or argument == "-lh":
logging = "logginghtml"
if argument == "--help" or argument == "-h":
print "GTK+ Key Status Monitor"
print "Monitors the status of keyboard and mouse keys."
print "Options:"
print "\t--no-decorations, -d: Do not show window decorations."
print "\t--logging-txt, -lt: Log keystrokes as text to stdout."
print "\t--logging-html, -lh: Log keystrokes as html-img-tags to stdout."
print "\t--help, -h: Show this help message!"
exit(0)
App = KeyStatusApp(decorated, logging)
gtk.main() # Start the GTK main loop