try:
    import Xlib.display
    import Xlib.X        
    import Xlib.XK
    import Xlib.error
    import Xlib.ext.xtest
    haveXlib = True
except ImportError:
    haveXlib = False

try:
    from ctypes import *
    import win32con
    haveWindows = True
except ImportError:
    haveWindows = False

class Action():
    def __init__(self,xLibKeyCode=-1,win32KeyCode=-1,shiftDown=False,controlDown=False,altDown=False,extend=False,mouseButton=False,mouseMovement=False):
        self.xLibKeyCode = xLibKeyCode
        self.win32KeyCode = win32KeyCode
        self.shiftDown = shiftDown
        self.controlDown = controlDown
        self.altDown = altDown
        self.extend = extend
        self.mouseButton = mouseButton
        self.mouseMovement = mouseMovement
        self.isDown = False

actions = {} 

if haveWindows:
    user32 = windll.user32
    PUL = POINTER(c_ulong)
    KEYEVENTF_EXTENDEDKEY = 0x0001
    KEYEVENTF_KEYUP = 0x0002
    KEYEVENTF_SCANCODE = 0x0008
    
    MOUSEEVENTF_LEFTDOWN   = 0x0002
    MOUSEEVENTF_LEFTUP     = 0x0004
    MOUSEEVENTF_RIGHTDOWN  = 0x0008
    MOUSEEVENTF_RIGHTUP    = 0x0010
    MOUSEEVENTF_MIDDLEDOWN = 0x0020
    MOUSEEVENTF_MIDDLEUP   = 0x0040
    MOUSEEVENTF_RELATIVE   = 0x0000
    MOUSEEVENTF_MOVE       = 0x0001
    MOUSEEVENTF_ABSOLUTE   = 0x8000
    MOUSEEVENTF_WHEEL      = 0x0080
    MOUSEEVENTF_XDOWN      = 0x0100
    MOUSEEVENTF_XUP        = 0x0200
    INPUT_MOUSE = 0x0000
    INPUT_KEYBOARD = 0x0001
    INPUT_HARDWARE = 0x0002    

    class KeyBdInput(Structure):
        _fields_ = [("wVk", c_ushort),
                 ("wScan", c_ushort),
                 ("dwFlags", c_ulong),
                 ("time", c_ulong),
                 ("dwExtraInfo", PUL)]
    
    class HardwareInput(Structure):
        _fields_ = [("uMsg", c_ulong),
                 ("wParamL", c_short),
                 ("wParamH", c_ushort)]
    
    class MouseInput(Structure):
        _fields_ = [("dx", c_long),
                 ("dy", c_long),
                 ("mouseData", c_ulong),
                 ("dwFlags", c_ulong),
                 ("time",c_ulong),
                 ("dwExtraInfo", PUL)]
    
    class Input_I(Union):
        _fields_ = [("ki", KeyBdInput),
                  ("mi", MouseInput),
                  ("hi", HardwareInput)]
    
    class Input(Structure):
        _fields_ = [("type", c_ulong),
                 ("ii", Input_I)]
    
    class POINT(Structure):
        _fields_ = [("x", c_ulong),
                 ("y", c_ulong)]

    nums  = "0123456789"
    chars = "abcdefghijklmnopqrstuvwxyz"
    for i in range(len(nums)):
        actions[nums[i]] = Action(win32KeyCode = 0x30 + i)
    for i in range(len(chars)):
        actions[chars[i]] = Action(win32KeyCode = 0x41 + i )
    actions["Arrow Left"] = Action(win32KeyCode = 0x25,extend=True )
    actions["Arrow Right"] = Action(win32KeyCode = 0x27,extend=True )
    actions["Arrow Up"] = Action(win32KeyCode = 0x26,extend=True )