Ejemplo n.º 1
0
 def stop(self):
     # FIXME: 经过测试发现,这个 stop 函数并不会正常工作。
     # 现在是将 thread 为 daemon thread,让线程在程序退出时停止。
     if self._started:
         loop = Quartz.CFRunLoopGetCurrent()
         Quartz.CFRunLoopStop(loop)
         self._t.join()
Ejemplo n.º 2
0
    def _setup_observer(self):
        self._ax_element = ApplicationServices.AXUIElementCreateApplication(
            self.pid)
        self._ax_observed = [
            ApplicationServices.kAXApplicationActivatedNotification,
            ApplicationServices.kAXApplicationDeactivatedNotification,
            ApplicationServices.kAXWindowResizedNotification,
            ApplicationServices.kAXWindowMovedNotification,
        ]
        err, self._observer = ApplicationServices.AXObserverCreate(
            self.pid, on_ax_event, None)
        if err != ApplicationServices.kAXErrorSuccess:
            raise AXAPIError(err)

        for item in self._ax_observed:
            err = ApplicationServices.AXObserverAddNotification(
                self._observer, self._ax_element, item, self.obj_pointer)
            if err != ApplicationServices.kAXErrorSuccess:
                raise AXAPIError(err)

        Quartz.CFRunLoopAddSource(
            Quartz.CFRunLoopGetCurrent(),
            ApplicationServices.AXObserverGetRunLoopSource(self._observer),
            Quartz.kCFRunLoopCommonModes,
        )
Ejemplo n.º 3
0
    def _run(self):
        self._loop = None
        try:
            tap = self._create_event_tap()
            if tap is None:
                self._mark_ready()
                return

            loop_source = Quartz.CFMachPortCreateRunLoopSource(
                None, tap, 0)
            self._loop = Quartz.CFRunLoopGetCurrent()

            Quartz.CFRunLoopAddSource(
                self._loop, loop_source, Quartz.kCFRunLoopDefaultMode)
            Quartz.CGEventTapEnable(tap, True)

            self._mark_ready()
            while self.running:
                result = Quartz.CFRunLoopRunInMode(
                    Quartz.kCFRunLoopDefaultMode, 1, False)
                try:
                    if result != Quartz.kCFRunLoopRunTimedOut:
                        break
                except AttributeError:
                    # This happens during teardown of the virtual machine
                    break

        finally:
            self._loop = None
Ejemplo n.º 4
0
def run_event_loop():
    LOG.info("try to load mac hotkey event loop")
    import Quartz
    from AppKit import NSSystemDefined

    # Set up a tap, with type of tap, location, options and event mask
    tap = Quartz.CGEventTapCreate(
        Quartz.kCGSessionEventTap,  # Session level is enough for our needs
        Quartz.kCGHeadInsertEventTap,  # Insert wherever, we do not filter
        Quartz.kCGEventTapOptionDefault,
        # NSSystemDefined for media keys
        Quartz.CGEventMaskBit(NSSystemDefined),
        keyboard_tap_callback,
        None
    )

    run_loop_source = Quartz.CFMachPortCreateRunLoopSource(
        None, tap, 0)
    Quartz.CFRunLoopAddSource(
        Quartz.CFRunLoopGetCurrent(),
        run_loop_source,
        Quartz.kCFRunLoopDefaultMode
    )
    # Enable the tap
    Quartz.CGEventTapEnable(tap, True)
    # and run! This won't return until we exit or are terminated.
    Quartz.CFRunLoopRun()
    LOG.error('Mac hotkey event loop exit')
    return []
Ejemplo n.º 5
0
    def __init__(self,*args,**kwargs):
        ioHubKeyboardDevice.__init__(self,*args,**kwargs['dconfig'])
        
        # TODO: This dict should be reset whenever monitoring is turned off for the device OR
        # whenever events are cleared fpr the device.
        # Same to do for the _active_modifiers bool lookup array
        self._last_general_mod_states=dict(shift_on=False,alt_on=False,cmd_on=False,ctrl_on=False)

        #self._codedict = {self._createStringForKey(code,0): code for code in range(128)}

        self._loop_source=None
        self._tap=None
        self._device_loop=None
        self._loop_mode=None        

        self._tap = Qz.CGEventTapCreate(
            Qz.kCGSessionEventTap,
            Qz.kCGHeadInsertEventTap,
            Qz.kCGEventTapOptionDefault,
            Qz.CGEventMaskBit(Qz.kCGEventKeyDown) |
            Qz.CGEventMaskBit(Qz.kCGEventKeyUp)|
            Qz.CGEventMaskBit(Qz.kCGEventFlagsChanged),
            self._nativeEventCallback,
            None)            
        
        self._CGEventTapEnable=Qz.CGEventTapEnable
        self._loop_source = Qz.CFMachPortCreateRunLoopSource(None, self._tap, 0)
        
        self._device_loop = Qz.CFRunLoopGetCurrent()
        
        self._loop_mode=Qz.kCFRunLoopDefaultMode

        Qz.CFRunLoopAddSource(self._device_loop, self._loop_source, self._loop_mode)
Ejemplo n.º 6
0
 def __init__(self,*args,**kwargs):
     MouseDevice.__init__(self,*args,**kwargs['dconfig'])
     
     self._tap = Qz.CGEventTapCreate(
         Qz.kCGSessionEventTap,
         Qz.kCGHeadInsertEventTap,
         Qz.kCGEventTapOptionDefault,
         Qz.CGEventMaskBit(Qz.kCGEventMouseMoved) |
         Qz.CGEventMaskBit(Qz.kCGEventLeftMouseDown) |
         Qz.CGEventMaskBit(Qz.kCGEventLeftMouseUp) |
         Qz.CGEventMaskBit(Qz.kCGEventRightMouseDown) |
         Qz.CGEventMaskBit(Qz.kCGEventRightMouseUp) |
         Qz.CGEventMaskBit(Qz.kCGEventLeftMouseDragged) |
         Qz.CGEventMaskBit(Qz.kCGEventRightMouseDragged) |
         Qz.CGEventMaskBit(Qz.kCGEventOtherMouseDragged) |
         Qz.CGEventMaskBit(Qz.kCGEventOtherMouseDown) |
         Qz.CGEventMaskBit(Qz.kCGEventScrollWheel) |
         Qz.CGEventMaskBit(Qz.kCGEventOtherMouseUp),
         self._nativeEventCallback,
         None)            
     
     self._scrollPositionX=0
     self._CGEventTapEnable=Qz.CGEventTapEnable
     self._loop_source = Qz.CFMachPortCreateRunLoopSource(None, self._tap, 0)          
     self._device_loop = Qz.CFRunLoopGetCurrent()
     self._loop_mode=Qz.kCFRunLoopDefaultMode
     
     Qz.CFRunLoopAddSource(self._device_loop, self._loop_source, self._loop_mode)
    def stop_event_loop(self):
        """
        Stop event loop.

        :return: None.
        """
        # Stop the current run loop
        Quartz.CFRunLoopStop(Quartz.CFRunLoopGetCurrent())
Ejemplo n.º 8
0
def filter_input():
    logging.info('Filtering all keys and mouse movements...')

    typed_keys = ''

    def keyboard_cb(proxy, type_, event, refcon):
        nonlocal typed_keys

        if not event:
            return None

        # Convert the Quartz CGEvent into something more useful
        ns_event = AppKit.NSEvent.eventWithCGEvent_(event)

        if not ns_event:
            return None

        if ns_event.type() == Quartz.kCGEventKeyDown:
            typed_keys += ns_event.characters()

            if typed_keys.endswith(EXIT_STRING):
                logging.info('Emergency exit!')

                Quartz.CFRunLoopStop(Quartz.CFRunLoopGetCurrent())

        # Filter every event
        return None

    logging.info('Creating tap...')
    # Set up a tap, with type of tap, location, options and event mask
    tap = Quartz.CGEventTapCreate(
        Quartz.kCGSessionEventTap,
        # Insert at the head so we can filter
        Quartz.kCGHeadInsertEventTap,
        # Enable filtering
        Quartz.kCGEventTapOptionDefault,
        # Act on all key and mouse events
        Quartz.kCGAnyInputEventType,
        # Our callback function
        keyboard_cb,
        None)

    runLoopSource = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)

    Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(),
                              runLoopSource,
                              Quartz.kCFRunLoopDefaultMode)

    Quartz.CGEventTapEnable(tap, True)

    logging.info('Starting run loop...')
    Quartz.CFRunLoopRun()

    logging.info('Run loop finished.')
Ejemplo n.º 9
0
def run_event_loop(player):
    LOG.info("try to load mac hotkey event loop")
    import Quartz
    from AppKit import NSKeyUp, NSSystemDefined, NSEvent

    def keyboard_tap_callback(proxy, type_, event, refcon):
        if type_ < 0 or type_ > 0x7fffffff:
            LOG.error('Unkown mac event')
            Quartz.CFRunLoopRun()
            return run_event_loop(ControllerApi.player)
        try:
            key_event = NSEvent.eventWithCGEvent_(event)
        except:
            LOG.info("mac event cast error")
            return event
        if key_event.subtype() == 8:
            key_code = (key_event.data1() & 0xFFFF0000) >> 16
            key_state = (key_event.data1() & 0xFF00) >> 8
            if key_code is 16 or key_code is 19 or key_code is 20:
                # 16 for play-pause, 19 for next, 20 for previous
                if key_state == NSKeyUp:
                    if key_code is 19:
                        player.play_next()
                    elif key_code is 20:
                        player.play_last()
                    elif key_code is 16:
                        player.play_or_pause()
                return None
        return event

    # Set up a tap, with type of tap, location, options and event mask
    tap = Quartz.CGEventTapCreate(
        Quartz.kCGSessionEventTap,  # Session level is enough for our needs
        Quartz.kCGHeadInsertEventTap,  # Insert wherever, we do not filter
        Quartz.kCGEventTapOptionDefault,
        # NSSystemDefined for media keys
        Quartz.CGEventMaskBit(NSSystemDefined),
        keyboard_tap_callback,
        None
    )

    run_loop_source = Quartz.CFMachPortCreateRunLoopSource(
        Quartz.kCFAllocatorDefault, tap, 0)
    Quartz.CFRunLoopAddSource(
        Quartz.CFRunLoopGetCurrent(),
        run_loop_source,
        Quartz.kCFRunLoopDefaultMode
    )
    # Enable the tap
    Quartz.CGEventTapEnable(tap, True)
    # and run! This won't return until we exit or are terminated.
    Quartz.CFRunLoopRun()
    LOG.error('Mac hotkey exit event ')
Ejemplo n.º 10
0
    def start(self):
        self.is_recording = True

        loop_source = Quartz.CFMachPortCreateRunLoopSource(
            None, self.event_tap, 0)
        loop = Quartz.CFRunLoopGetCurrent()

        Quartz.CFRunLoopAddSource(loop, loop_source,
                                  Quartz.kCFRunLoopDefaultMode)
        Quartz.CGEventTapEnable(self.event_tap, True)

        while self.is_recording:
            Quartz.CFRunLoopRunInMode(Quartz.kCFRunLoopDefaultMode, 5, False)
Ejemplo n.º 11
0
def run_event_loop():
    logger.info('try to load mac hotkey event loop')

    # Set up a tap, with type of tap, location, options and event mask

    def create_tap():
        return Quartz.CGEventTapCreate(
            Quartz.kCGSessionEventTap,  # Session level is enough for our needs
            Quartz.kCGHeadInsertEventTap,  # Insert wherever, we do not filter
            Quartz.kCGEventTapOptionDefault,
            # NSSystemDefined for media keys
            Quartz.CGEventMaskBit(NSSystemDefined),
            keyboard_tap_callback,
            None)

    tap = create_tap()
    if tap is None:
        logger.error('Error occurred when trying to listen global hotkey. '
                     'trying to popup a prompt dialog to ask for permission.')
        # we do not use pyobjc-framework-ApplicationServices directly, since it
        # causes segfault when call AXIsProcessTrustedWithOptions function
        import objc
        AS = objc.loadBundle(
            'CoreServices', globals(),
            '/System/Library/Frameworks/ApplicationServices.framework')
        objc.loadBundleFunctions(AS, globals(),
                                 [('AXIsProcessTrustedWithOptions', b'Z@')])
        objc.loadBundleVariables(AS, globals(),
                                 [('kAXTrustedCheckOptionPrompt', b'@')])
        trusted = AXIsProcessTrustedWithOptions(
            {kAXTrustedCheckOptionPrompt: True})  # noqa
        if not trusted:
            logger.info(
                'Have popuped a prompt dialog to ask for accessibility.'
                'You can restart feeluown after you grant access to it.')
        else:
            logger.warning('Have already grant accessibility, '
                           'but we still can not listen global hotkey,'
                           'theoretically, this should not happen.')
        return

    run_loop_source = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
    Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(), run_loop_source,
                              Quartz.kCFRunLoopDefaultMode)
    # Enable the tap
    Quartz.CGEventTapEnable(tap, True)
    # and run! This won't return until we exit or are terminated.
    Quartz.CFRunLoopRun()
    logger.error('mac hotkey event loop exit')
    return []
Ejemplo n.º 12
0
    def on(self):
        mask = Quartz.CGEventMaskBit(Quartz.kCGEventKeyDown)
        tap = Quartz.CGEventTapCreate(Quartz.kCGSessionEventTap,
                                      Quartz.kCGHeadInsertEventTap, 0, mask,
                                      self._event_call_back, None)

        assert tap, "failed to create event tap"

        run_loop_source = Quartz.CFMachPortCreateRunLoopSource(
            Quartz.kCFAllocatorDefault, tap, 0)
        Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(),
                                  run_loop_source,
                                  Quartz.kCFRunLoopCommonModes)
        Quartz.CGEventTapEnable(tap, True)
        Quartz.CFRunLoopRun()
Ejemplo n.º 13
0
    def run(self):
        tap = Quartz.CGEventTapCreate(
            Quartz.kCGSessionEventTap, Quartz.kCGHeadInsertEventTap,
            Quartz.kCGEventTapOptionDefault,
            Quartz.CGEventMaskBit(Quartz.kCGEventKeyDown)
            | Quartz.CGEventMaskBit(Quartz.kCGEventKeyUp), self.handler, None)

        loopsource = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
        self.loop = Quartz.CFRunLoopGetCurrent()
        Quartz.CFRunLoopAddSource(self.loop, loopsource,
                                  Quartz.kCFRunLoopDefaultMode)
        Quartz.CGEventTapEnable(tap, True)

        while self.state:
            Quartz.CFRunLoopRunInMode(Quartz.kCFRunLoopDefaultMode, 5, False)
Ejemplo n.º 14
0
    def runEventsCapture(self):
        import AppKit
        pool = AppKit.NSAutoreleasePool.alloc().init()
        from AppKit import NSSystemDefined

        import Quartz
        self.runLoopRef = Quartz.CFRunLoopGetCurrent()

        while True:
            # https://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html
            try:
                tap = Quartz.CGEventTapCreate(
                    Quartz.
                    kCGSessionEventTap,  # Quartz.kCGSessionEventTap or kCGHIDEventTap
                    Quartz.
                    kCGHeadInsertEventTap,  # Insert wherever, we do not filter
                    Quartz.
                    kCGEventTapOptionDefault,  # we can't listen-only because we want to consume it
                    Quartz.CGEventMaskBit(
                        NSSystemDefined),  # NSSystemDefined for media keys
                    self.eventTap,
                    None)
            except TypeError:
                # wrong number of args? I got this on MacOSX 10.6,
                # where it expected 5 args (instead of 6).
                # however, it crashes when I call it without the last arg!
                assert False, "CGEventTapCreate has an invalid signature on your system. This is fixed in later MacOSX versions. It should work in at least >=MacOSX 10.8. It is known to be broken in MacOSX 10.6."
            assert tap

            # Create a runloop source and add it to the current loop
            runLoopSource = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
            Quartz.CFRunLoopAddSource(self.runLoopRef, runLoopSource,
                                      Quartz.kCFRunLoopDefaultMode)

            # Enable the tap
            Quartz.CGEventTapEnable(tap, True)

            try:
                # and run! This won't return until we exit or are terminated.
                Quartz.CFRunLoopRun()
            except Exception:
                sys.excepthook(*sys.exc_info())
                continue  # rerun

            # this is a regular quit
            break

        del pool
Ejemplo n.º 15
0
    def run(self):
        """ Creates a listener and loops while waiting for an event. Intended to run as
        a background thread. """
        self.tap = Quartz.CGEventTapCreate(
            Quartz.kCGSessionEventTap, Quartz.kCGHeadInsertEventTap,
            Quartz.kCGEventTapOptionDefault,
            Quartz.CGEventMaskBit(Quartz.kCGEventKeyDown)
            | Quartz.CGEventMaskBit(Quartz.kCGEventKeyUp)
            | Quartz.CGEventMaskBit(Quartz.kCGEventFlagsChanged), self.handler,
            None)
        loopsource = Quartz.CFMachPortCreateRunLoopSource(None, self.tap, 0)
        loop = Quartz.CFRunLoopGetCurrent()
        Quartz.CFRunLoopAddSource(loop, loopsource,
                                  Quartz.kCFRunLoopDefaultMode)
        Quartz.CGEventTapEnable(self.tap, True)

        while self.listening:
            Quartz.CFRunLoopRunInMode(Quartz.kCFRunLoopDefaultMode, 5, False)
Ejemplo n.º 16
0
 def runEventsCapture(cls, controlPath):
     tapHandler = cls(controlPath)
     tap = Quartz.CGEventTapCreate(
         Quartz.kCGSessionEventTap,  # Session level is enough for our needs
         Quartz.kCGHeadInsertEventTap,  # Insert wherever, we do not filter
         Quartz.kCGEventTapOptionListenOnly,  # Listening is enough
         # NSSystemDefined for media keys
         Quartz.CGEventMaskBit(NSSystemDefined),
         tapHandler.eventTap,
         None)
     # Create a runloop source and add it to the current loop
     runLoopSource = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
     Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(), runLoopSource,
                               Quartz.kCFRunLoopDefaultMode)
     # Enable the tap
     Quartz.CGEventTapEnable(tap, True)
     # and run! This won't return until we exit or are terminated.
     Quartz.CFRunLoopRun()
Ejemplo n.º 17
0
def keyHook():
    tap = Quartz.CGEventTapCreate(Quartz.kCGHIDEventTap,
                                  Quartz.kCGHeadInsertEventTap,
                                  Quartz.kCGEventTapOptionDefault,
                                  Quartz.kCGEventMaskForAllEvents,
                                  keyboardTapCallback, None)

    if tap is None:
        print('failed to create event tap!')
        sys.exit(1)

    runLoopSource = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
    Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(), runLoopSource,
                              Quartz.kCFRunLoopDefaultMode)

    Quartz.CGEventTapEnable(tap, True)

    Quartz.CFRunLoopRun()
Ejemplo n.º 18
0
class EventTap(object):
    """ wraps a Quartz keyboard event tap """
    def __init__(self, cb, block_cb):
        self.runner = EventTapRunner.alloc().init()

        self.setup_event_tap(cb, block_cb)

    def setup_event_tap(self, callback, should_block):
        def keyboardTapCallback(proxy, type_, event, refcon):
            if type_ == Quartz.kCGEventTapDisabledByTimeout & 0xffffffff:
                # event tap timed out, re-enable.
                Quartz.CGEventTapEnable(self.tap, True)
                NSLog('event tap timed out, re-enabling')
                return None

            # Convert the Quartz CGEvent into something more useful
            keyEvent = NSEvent.eventWithCGEvent_(event)
            try:
                selector = objc.selector(self.runner.call_, signature='v@:@')
                self.runner.performSelectorOnMainThread_withObject_waitUntilDone_(
                    selector, (callback, keyEvent), False)

                if should_block(keyEvent):
                    return None
            except Exception, e:
                tb = sys.exc_info()
                print ''.join(traceback.format_exception(*tb))
                print 'Exception: ' + e.message

            return event

        self.tap = Quartz.CGEventTapCreate(
            Quartz.kCGSessionEventTap, Quartz.kCGHeadInsertEventTap,
            Quartz.kCGEventTapOptionDefault,
            Quartz.CGEventMaskBit(Quartz.kCGEventKeyDown), keyboardTapCallback,
            None)

        runLoopSource = Quartz.CFMachPortCreateRunLoopSource(None, self.tap, 0)
        Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(), runLoopSource,
                                  Quartz.kCFRunLoopDefaultMode)
        # Enable the tap
        Quartz.CGEventTapEnable(self.tap, True)

        Quartz.CFRunLoopRun()
Ejemplo n.º 19
0
    def runEventsCapture(self):
        import AppKit, Quartz
        from AppKit import NSSystemDefined
        pool = AppKit.NSAutoreleasePool.alloc().init()

        self.runLoopRef = Quartz.CFRunLoopGetCurrent()

        while True:
            # https://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html
            tap = Quartz.CGEventTapCreate(
                Quartz.
                kCGSessionEventTap,  # Quartz.kCGSessionEventTap or kCGHIDEventTap
                Quartz.
                kCGHeadInsertEventTap,  # Insert wherever, we do not filter
                Quartz.
                kCGEventTapOptionDefault,  #Quartz.kCGEventTapOptionListenOnly,
                Quartz.CGEventMaskBit(
                    NSSystemDefined),  # NSSystemDefined for media keys
                self.eventTap,
                None)
            assert tap

            # Create a runloop source and add it to the current loop
            runLoopSource = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
            Quartz.CFRunLoopAddSource(self.runLoopRef, runLoopSource,
                                      Quartz.kCFRunLoopDefaultMode)

            # Enable the tap
            Quartz.CGEventTapEnable(tap, True)

            try:
                # and run! This won't return until we exit or are terminated.
                Quartz.CFRunLoopRun()
            except Exception:
                # I got this one here once:
                # error: NSInternalInconsistencyException - Invalid parameter not satisfying: cgsEvent.type > 0 && cgsEvent.type <= kCGSLastEventType
                sys.excepthook(*sys.exc_info())
                continue  # rerun

            # this is a regular quit
            break

        del pool
Ejemplo n.º 20
0
    def _run(self):
        self.IS_TRUSTED = HIServices.AXIsProcessTrusted()
        if not self.IS_TRUSTED:
            self._log.warning(
                'This process is not trusted! Input event monitoring will not '
                'be possible until it is added to accessibility clients.')

        self._loop = None
        try:
            tap = self._create_event_tap()
            if tap is None:
                self._mark_ready()
                return

            loop_source = Quartz.CFMachPortCreateRunLoopSource(
                None, tap, 0)
            self._loop = Quartz.CFRunLoopGetCurrent()

            Quartz.CFRunLoopAddSource(
                self._loop, loop_source, Quartz.kCFRunLoopDefaultMode)
            Quartz.CGEventTapEnable(tap, True)

            self._mark_ready()

            # pylint: disable=W0702; we want to silence errors
            try:
                while self.running:
                    result = Quartz.CFRunLoopRunInMode(
                        Quartz.kCFRunLoopDefaultMode, 1, False)
                    try:
                        if result != Quartz.kCFRunLoopRunTimedOut:
                            break
                    except AttributeError:
                        # This happens during teardown of the virtual machine
                        break

            except:
                # This exception will have been passed to the main thread
                pass
            # pylint: enable=W0702

        finally:
            self._loop = None
Ejemplo n.º 21
0
 def _setup_tap(self):
     events = [
         Quartz.kCGEventLeftMouseDown,
         Quartz.kCGEventRightMouseDown,
         Quartz.kCGEventKeyDown,
     ]
     events = [Quartz.CGEventMaskBit(e) for e in events]
     event_mask = reduce(lambda a, b: a | b, events)
     self._tap = Quartz.CGEventTapCreate(
         Quartz.kCGAnnotatedSessionEventTap,
         Quartz.kCGTailAppendEventTap,
         Quartz.
         kCGEventTapOptionListenOnly,  # TODO: Tap keydown synchronously
         event_mask,
         self._on_input,
         None,
     )
     source = Quartz.CFMachPortCreateRunLoopSource(None, self._tap, 0)
     Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(), source,
                               Quartz.kCFRunLoopCommonModes)
Ejemplo n.º 22
0
    def run(self):
        self._tap = Quartz.CGEventTapCreate(
            Quartz.kCGSessionEventTap, # Session level is enough for our needs
            Quartz.kCGHeadInsertEventTap, # Insert wherever, we do not filter
            # Active, to swallow the play/pause event is enough
            Quartz.kCGEventTapOptionDefault,
            # NSSystemDefined for media keys
            Quartz.CGEventMaskBit(NSSystemDefined),
            self._event_tap,
            None
        )

        # the above can fail
        if self._tap is None:
            self._event.set()
            return

        self._loop = Quartz.CFRunLoopGetCurrent()

        # add an observer so we know when we can stop it
        # without a race condition
        self._observ = Quartz.CFRunLoopObserverCreate(
            None, Quartz.kCFRunLoopEntry, False, 0, self._loop_start, None)
        Quartz.CFRunLoopAddObserver(
            self._loop, self._observ, Quartz.kCFRunLoopCommonModes)

        # Create a runloop source and add it to the current loop
        self._runLoopSource = Quartz.CFMachPortCreateRunLoopSource(
            None, self._tap, 0)

        Quartz.CFRunLoopAddSource(
            self._loop,
            self._runLoopSource,
            Quartz.kCFRunLoopDefaultMode
        )

        # Enable the tap
        Quartz.CGEventTapEnable(self._tap, True)

        # runrunrun
        Quartz.CFRunLoopRun()
Ejemplo n.º 23
0
    def keyboard_cb(proxy, type_, event, refcon):
        nonlocal typed_keys

        if not event:
            return None

        # Convert the Quartz CGEvent into something more useful
        ns_event = AppKit.NSEvent.eventWithCGEvent_(event)

        if not ns_event:
            return None

        if ns_event.type() == Quartz.kCGEventKeyDown:
            typed_keys += ns_event.characters()

            if typed_keys.endswith(EXIT_STRING):
                logging.info('Emergency exit!')

                Quartz.CFRunLoopStop(Quartz.CFRunLoopGetCurrent())

        # Filter every event
        return None
Ejemplo n.º 24
0
    def _run(self):
        self._loop = None
        try:
            tap = self._create_event_tap()
            if tap is None:
                self._mark_ready()
                return

            loop_source = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
            self._loop = Quartz.CFRunLoopGetCurrent()

            Quartz.CFRunLoopAddSource(self._loop, loop_source,
                                      Quartz.kCFRunLoopDefaultMode)
            Quartz.CGEventTapEnable(tap, True)

            self._mark_ready()

            # pylint: disable=W0702; we want to silence errors
            try:
                while self.running:
                    result = Quartz.CFRunLoopRunInMode(
                        Quartz.kCFRunLoopDefaultMode, 1, False)
                    try:
                        if result != Quartz.kCFRunLoopRunTimedOut:
                            break
                    except AttributeError:
                        # This happens during teardown of the virtual machine
                        break

            except:
                # This exception will have been passed to the main thread
                import traceback
                traceback.print_exc()
                pass
            # pylint: enable=W0702

        finally:
            self._loop = None
Ejemplo n.º 25
0
    def __init__(self):
        """
        Constructor.

        :return: None.
        """
        # Create event tap
        self._tap = Quartz.CGEventTapCreate(
            # The tap is for session events
            Quartz.kCGSessionEventTap,
            # The tap is inserted before existing event taps
            Quartz.kCGHeadInsertEventTap,
            # The tap is active filter
            Quartz.kCGEventTapOptionDefault,
            # The tap listens to all events
            Quartz.kCGEventMaskForAllEvents,
            # The tap calls this callback
            self._tap_callback,
            # User-defined data
            None)

        # Create run loop source
        run_loop_source = Quartz.CFMachPortCreateRunLoopSource(
            None, self._tap, 0)

        # Add run loop source to the current run loop
        Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(),
                                  run_loop_source,
                                  Quartz.kCFRunLoopDefaultMode)

        # Key-down event handler
        self.KeyDown = None

        # Key-up event handler
        self.KeyUp = None

        # Mouse-down event handler
        self.MouseDown = None

        # Mouse-up event handler
        self.MouseUp = None

        # Mouse wheel event handler
        self.MouseWheel = None

        # Mouse move event handler
        self.MouseMove = None

        # Modifier states that indicate whether each modifier is on or off.
        self._modifier_states = {
            'LCTRL': 0,
            'RCTRL': 0,
            'LCMD': 0,
            'RCMD': 0,
            'LALT': 0,
            'RALT': 0,
            'LSHIFT': 0,
            'RSHIFT': 0,
            'CAPSLOCK': 0,
        }

        # Get current timestamp
        current_timestamp = NSDate.date().timeIntervalSince1970()

        # Get interval since the system boot time
        system_up_interval = NSProcessInfo.processInfo().systemUptime()

        # Get the system boot time's timestamp.
        # This is used for calculating each event's timestamp.
        self._system_up_timestamp = current_timestamp - system_up_interval
Ejemplo n.º 26
0
import Quartz


def MyFunction(p, t, e, c):
    print e


tap = Quartz.CGEventTapCreate(
    Quartz.kCGHIDEventTap, Quartz.kCGHeadInsertEventTap,
    Quartz.kCGEventTapOptionListenOnly,
    Quartz.CGEventMaskBit(Quartz.kCGEventLeftMouseDown), MyFunction, None)

runLoopSource = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(), runLoopSource,
                          Quartz.kCFRunLoopDefaultMode)
Quartz.CGEventTapEnable(tap, True)

Quartz.CFRunLoopRun()
click = Quartz.CGEventTapCreate(
    Quartz.kCGSessionEventTap, Quartz.kCGHeadInsertEventTap,
    Quartz.kCGEventTapOptionListenOnly,
    Quartz.CGEventMaskBit(Quartz.kCGEventLeftMouseUp), mouseClickCallback,
    None)

mod = Quartz.CGEventTapCreate(
    Quartz.kCGSessionEventTap, Quartz.kCGHeadInsertEventTap,
    Quartz.kCGEventTapOptionListenOnly,
    Quartz.CGEventMaskBit(Quartz.kCGEventFlagsChanged), modifierTapCallback,
    None)

# Add the mask to the run
runLoopSource_tap = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(), runLoopSource_tap,
                          Quartz.kCFRunLoopDefaultMode)

runLoopSource_click = Quartz.CFMachPortCreateRunLoopSource(None, click, 0)
Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(), runLoopSource_click,
                          Quartz.kCFRunLoopDefaultMode)

runLoopSource_mod = Quartz.CFMachPortCreateRunLoopSource(None, mod, 0)
Quartz.CFRunLoopAddSource(Quartz.CFRunLoopGetCurrent(), runLoopSource_mod,
                          Quartz.kCFRunLoopDefaultMode)

Quartz.CGEventTapEnable(tap, True)
Quartz.CGEventTapEnable(click, True)
Quartz.CGEventTapEnable(mod, True)

# Main loop