def __init__(self, log_event_details=False): threading.Thread.__init__(self) self.finished = threading.Event() self.log_events = log_event_details self.log_events_file = None # Give these some initial values self.mouse_position_x = 0 self.mouse_position_y = 0 # Assign default function actions (do nothing). self.KeyDown = lambda x: True self.KeyUp = lambda x: True self.MouseAllButtonsDown = lambda x: True self.MouseAllButtonsUp = lambda x: True self.MouseAllMotion = lambda x: True self.contextEventMask = [X.KeyPress, X.MotionNotify] # Used to hold any keys currently pressed and the repeat count # of each key. self.key_states = dict() self.contextEventMask = [X.KeyPress, X.MotionNotify] # Hook to our display. self.local_dpy = display.Display() self.record_dpy = display.Display() self.ioHubMouseButtonMapping = { 1: 'MOUSE_BUTTON_LEFT', 2: 'MOUSE_BUTTON_MIDDLE', 3: 'MOUSE_BUTTON_RIGHT' } self.pressedMouseButtons = 0 self.scroll_y = 0 # Direct xlib ctypes wrapping for better / faster keyboard event -> key, # char field mapping. self._xlib = _xlib self._xdisplay = _xlib.XOpenDisplay(None) self._xroot = _xlib.XDefaultRootWindow(self._xdisplay) self._keysym = _xlib.KeySym() self._compose = _xlib.XComposeStatus() self._tmp_compose = _xlib.XComposeStatus() self._revert = ct.c_int(0) self._charbuf = (ct.c_char * 17)() self._cwin = _xlib.Window() self._revert_to_return = ct.c_int() self._xkey_evt = _xlib.XKeyEvent() self._xkey_evt.serial = 1 # not known, make it up. self._xkey_evt.send_event = 0 self._xkey_evt.subwindow = 0 self._xkey_evt.display = self._xdisplay self._xkey_evt.root = self._xroot #', Window), self._xkey_evt.subwindow = 0 #', Window)
def __init__(self, display_name=':0'): """Constructor Args: display_name: The X window display name. """ self._display = xlib.XOpenDisplay(display_name) self._window = xlib.XDefaultRootWindow(self._display) self._data = [] self._register() # Consumes the very first traffic within the connection with X server. xlib.XFlush(self._display)
def run(self): # control connection self.control_dpy = xlib.XOpenDisplay(None) xlib.XSynchronize(self.control_dpy, True) # unmapped replay window self.replay_dpy = xlib.XOpenDisplay(None) self.custom_atom = xlib.XInternAtom(self.replay_dpy, b"SCREENKEY", False) replay_fd = xlib.XConnectionNumber(self.replay_dpy) self.replay_win = create_replay_window(self.replay_dpy) if self.input_types & InputType.keyboard: self._kbd_init() # initialize recording context ev_ranges = [] dev_ranges = [] if self.input_types & InputType.keyboard: ev_ranges.append([xlib.FocusIn, xlib.FocusOut]) dev_ranges.append([xlib.KeyPress, xlib.KeyRelease]) if self.input_types & InputType.button: dev_ranges.append([xlib.ButtonPress, xlib.ButtonRelease]) if self.input_types & InputType.movement: dev_ranges.append([xlib.MotionNotify, xlib.MotionNotify]) self.record_ctx = record_context(self.control_dpy, ev_ranges, dev_ranges) record_dpy = xlib.XOpenDisplay(None) record_fd = xlib.XConnectionNumber(record_dpy) # we need to keep the record_ref alive(!) record_ref = record_enable(record_dpy, self.record_ctx, self._event_received) # event loop self.lock.release() while True: with self.lock: if self.stopped: break r_fd = [] if xlib.XPending(record_dpy): r_fd.append(record_fd) if xlib.XPending(self.replay_dpy): r_fd.append(replay_fd) if not r_fd: r_fd, _, _ = select.select([record_fd, replay_fd], [], []) if not r_fd: break if record_fd in r_fd: xlib.XRecordProcessReplies(record_dpy) xlib.XFlush(self.replay_dpy) if replay_fd in r_fd: ev = xlib.XEvent() xlib.XNextEvent(self.replay_dpy, xlib.byref(ev)) if self.input_types & InputType.keyboard: self._kbd_process(ev) # finalize xlib.XRecordFreeContext(self.control_dpy, self.record_ctx) xlib.XCloseDisplay(self.control_dpy) xlib.XCloseDisplay(record_dpy) del record_ref if self.input_types & InputType.keyboard: self._kbd_del() xlib.XDestroyWindow(self.replay_dpy, self.replay_win) xlib.XCloseDisplay(self.replay_dpy)
def run(self): self.control_dpy = xlib.XOpenDisplay(None) xlib.XSynchronize(self.control_dpy, True) self.record_ctx = record_context(self.control_dpy, [xlib.FocusIn, xlib.FocusOut], [xlib.KeyPress, xlib.KeyRelease]) record_dpy = xlib.XOpenDisplay(None) record_fd = xlib.XConnectionNumber(record_dpy) # note that we never ever map the window self.replay_dpy = xlib.XOpenDisplay(None) self.custom_atom = xlib.XInternAtom(self.replay_dpy, "SCREENKEY", False) replay_fd = xlib.XConnectionNumber(self.replay_dpy) self.replay_win = create_replay_window(self.replay_dpy) if self.compose: style = xlib.XIMPreeditNothing | xlib.XIMStatusNothing else: style = xlib.XIMPreeditNone | xlib.XIMStatusNone # TODO: implement preedit callbacks for on-the-spot composition # (this would fix focus-stealing for the global IM state) replay_xim = xlib.XOpenIM(self.replay_dpy, None, None, None) if not replay_xim: raise Exception("Cannot initialize input method") self.replay_xic = xlib.XCreateIC(replay_xim, xlib.XNClientWindow, self.replay_win, xlib.XNInputStyle, style, None) xlib.XSetICFocus(self.replay_xic) # we need to keep the proc_ref alive proc_ref = record_enable(record_dpy, self.record_ctx, self._event_received) last_ev = xlib.XEvent() self.lock.release() while True: with self.lock: if self.stopped: break r_fd = [] if xlib.XPending(record_dpy): r_fd.append(record_fd) if xlib.XPending(self.replay_dpy): r_fd.append(replay_fd) if not r_fd: r_fd, _, _ = select.select([record_fd, replay_fd], [], []) if not r_fd: break if record_fd in r_fd: xlib.XRecordProcessReplies(record_dpy) xlib.XFlush(self.replay_dpy) if replay_fd in r_fd: ev = xlib.XEvent() xlib.XNextEvent(self.replay_dpy, xlib.byref(ev)) if ev.type == xlib.ClientMessage and \ ev.xclient.message_type == self.custom_atom: if ev.xclient.data[0] in [xlib.FocusIn, xlib.FocusOut]: # We do not keep track of multiple XICs, just reset xic = xlib.Xutf8ResetIC(self.replay_xic) if xic is not None: xlib.XFree(xic) continue elif ev.type in [xlib.KeyPress, xlib.KeyRelease]: ev.xkey.send_event = False ev.xkey.window = self.replay_win filtered = bool(xlib.XFilterEvent(ev, 0)) if ev.type not in [xlib.KeyPress, xlib.KeyRelease]: continue if ev.type == xlib.KeyRelease and \ phantom_release(self.replay_dpy, ev.xkey): continue data = KeyData() data.filtered = filtered data.pressed = (ev.type == xlib.KeyPress) data.repeated = (ev.type == last_ev.type and \ ev.xkey.state == last_ev.xkey.state and \ ev.xkey.keycode == last_ev.xkey.keycode) data.mods_mask = ev.xkey.state self._event_modifiers(ev.xkey, data) if not data.filtered and data.pressed and self.translate: self._event_keypress(ev.xkey, data) else: self._event_lookup(ev.xkey, data) self._event_processed(data) last_ev = ev xlib.XRecordFreeContext(self.control_dpy, self.record_ctx) xlib.XCloseDisplay(self.control_dpy) xlib.XCloseDisplay(record_dpy) del proc_ref xlib.XDestroyIC(self.replay_xic) xlib.XCloseIM(replay_xim) xlib.XDestroyWindow(self.replay_dpy, self.replay_win) xlib.XCloseDisplay(self.replay_dpy)