Exemple #1
0
int main(int argc, const char *argv[]) {

    // Create an event tap to retrieve keypresses.
    CGEventMask eventMask = (CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventFlagsChanged));
    CFMachPortRef eventTap = CGEventTapCreate(
        kCGSessionEventTap, kCGHeadInsertEventTap, 0, eventMask, CGEventCallback, NULL
    );

    // Exit the program if unable to create the event tap.
    if(!eventTap) {
        fprintf(stderr, "ERROR: Unable to create event tap.\n");
        exit(1);
    }

    // Create a run loop source and add enable the event tap.
    CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
    CGEventTapEnable(eventTap, true);
    
    initscr();
    int row, col;
    getmaxyx(stdscr,row,col);
    clear();
    mvprintw(row/2,(col-10)/2,"0.000000%%");   
    refresh();
    CFRunLoopRun();

    return 0;
}
Exemple #2
0
int main(void) {

  fprintf(stderr, "Starting up.\n");
  CFMachPortRef      eventTap;
  CFRunLoopSourceRef runLoopSource;

  CGEventFlags oldFlags = CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState);
  eventTap = CGEventTapCreate(kCGSessionEventTap,
                              kCGHeadInsertEventTap,
                              0,
                              kCGEventMaskForAllEvents,
                              //CGEventMaskBit(kCGEventFlagsChanged) | CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventKeyUp),
                              myCGEventCallback,
                              &oldFlags);
  if (!eventTap) {
    fprintf(stderr, "Failed to create event tap!\n");
    exit(1);
  }

  runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
  CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
  CGEventTapEnable(eventTap, true);
  CFRunLoopRun();

  exit(0);

}
void MouseEventTool::AddHook()
{
    CGEventMask eventMask;
    CFRunLoopSourceRef runLoopSource;
    ProcessSerialNumber psn;

    myself = this;

    OSErr err = GetCurrentProcess(&psn);
    if (err) {
        return;
    }

    // Create an event tap.
    eventMask = kCGEventMaskForAllEvents;

    eventTap_ = CGEventTapCreateForPSN((void*) &psn, kCGHeadInsertEventTap, 0, eventMask, myCGEventCallback, NULL);
    //eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0, eventMask, myCGEventCallback, NULL);

    if (!eventTap_) {
        exit(1);
    }

    // Create a run loop source.
    runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap_, 0);

    // Add to the current run loop.
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,  kCFRunLoopCommonModes);

    // Enable the event tap.
    CGEventTapEnable(eventTap_, true);

}
Exemple #4
0
Status EventTappingEventPublisher::restart() {
  stop();
  WriteLock lock(run_loop_mutex_);
  run_loop_ = CFRunLoopGetCurrent();

  CGEventMask mask = kCGEventNull;
  if (FLAGS_enable_keyboard_events) {
    mask |= 1 << kCGEventKeyDown;
  }

  if (FLAGS_enable_mouse_events) {
    mask |= 1 << kCGEventLeftMouseDown;
  }

  event_tap_ = CGEventTapCreate(kCGSessionEventTap,
                                kCGHeadInsertEventTap,
                                kCGEventTapOptionListenOnly,
                                mask,
                                eventCallback,
                                nullptr);
  if (event_tap_ == nullptr) {
    run_loop_ = nullptr;
    return Status(1, "Could not create event tap");
  }
  run_loop_source_ =
      CFMachPortCreateRunLoopSource(kCFAllocatorDefault, event_tap_, 0);
  CFRunLoopAddSource(run_loop_, run_loop_source_, kCFRunLoopCommonModes);
  CGEventTapEnable(event_tap_, true);
  return Status(0);
}
Exemple #5
0
void startListen(){
    CFMachPortRef	  eventTap;
    CGEventMask		eventMask;
    CFRunLoopSourceRef runLoopSource;
    
    // Create an event tap. We are interested in key presses.
    //eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp) | (1 << kCGEventFlagsChanged));
    eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventFlagsChanged));
    eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
                                eventMask, myCGEventCallback, NULL);
    if (!eventTap) {
        fprintf(stderr, "failed to create event tap\n");
        exit(1);
    }
    
    // Create a run loop source.
    runLoopSource = CFMachPortCreateRunLoopSource(
                                                  kCFAllocatorDefault, eventTap, 0);
    // Add to the current run loop.
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
                       kCFRunLoopCommonModes);
    
    // Enable the event tap.
    CGEventTapEnable(eventTap, true);
    
    // Set it all running.
    CFRunLoopRun();
    
    // In a real program, one would have arranged for cleaning up.
}
Exemple #6
0
int main(int argc, char **argv)
{
    if(CheckArguments(argc, argv))
        return 0;

    KwmInit();
    KWMMach.EventMask = ((1 << kCGEventKeyDown) |
                         (1 << kCGEventKeyUp) |
                         (1 << kCGEventMouseMoved));

    KWMMach.EventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, KWMMach.EventMask, CGEventCallback, NULL);
    if(!KWMMach.EventTap || !CGEventTapIsEnabled(KWMMach.EventTap))
        Fatal("ERROR: Could not create event-tap!");

    CFRunLoopAddSource(CFRunLoopGetMain(),
                       CFMachPortCreateRunLoopSource(kCFAllocatorDefault, KWMMach.EventTap, 0),
                       kCFRunLoopCommonModes);

    CGEventTapEnable(KWMMach.EventTap, true);
    CreateWorkspaceWatcher(KWMMach.WorkspaceWatcher);

    // NOTE(koekeishiya): Initialize AXLIB
    // AXLibInit(&AXApplications);
    // AXLibRunningApplications();

    NSApplicationLoad();
    CFRunLoopRun();
    return 0;
}
Exemple #7
0
int main(int argc, const char *argv[]) {
    
    struct timespec ts;
    current_utc_time(&ts);
    
    //printf("s:  %lu\n", ts.tv_sec);
    //printf("ns: %lu\n", ts.tv_nsec);

    // Create an event tap to retrieve keypresses.
    CGEventMask eventMask = (CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventFlagsChanged));
    CFMachPortRef eventTap = CGEventTapCreate(
        kCGSessionEventTap, kCGHeadInsertEventTap, 0, eventMask, CGEventCallback, NULL
    );

    // Exit the program if unable to create the event tap.
    if(!eventTap) {
        fprintf(stderr, "ERROR: Unable to create event tap.\n");
        exit(1);
    }

    // Create a run loop source and add enable the event tap.
    CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
    CGEventTapEnable(eventTap, true);


    // Clear the logfile if clear argument used or log to specific file if given.
    if(argc == 2) {
        if(strcmp(argv[1], "clear") == 0) {
            fopen(logfileLocation, "w");
            printf("%s cleared.\n", logfileLocation);
            fflush(stdout);
            exit(1);
        } else {
            logfileLocation = argv[1];
        }
    }

    // Get the current time and open the logfile.
    time_t result = time(NULL);
    logfile = fopen(logfileLocation, "a");
    
    if (!logfile) {
        fprintf(stderr, "ERROR: Unable to open log file. Ensure that you have the proper permissions.\n");
        exit(1);
    }

    // Output to logfile.
    fprintf(logfile, "\n\nKeylogging has begun.\n%s\n", asctime(localtime(&result)));
    fflush(logfile);

    // Display the location of the logfile and start the loop.
    printf("Logging to: %s\n", logfileLocation);
    
    fflush(stdout);
    CFRunLoopRun();

    return 0;
}
Exemple #8
0
int main(int argc, char *argv[]) {
  CGEventMask mask = CGEventMaskBit(kCGEventScrollWheel);
  CFMachPortRef port = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, mask, &callback, NULL);
  if(port == NULL)
    return -1;
  CFRunLoopSourceRef source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, port, 0);
  CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
  CGEventTapEnable(port, true);
  CFRunLoopRun();
  return 1;
}
Exemple #9
0
int
key_stop(void)
{
	if (eventTap == NULL) {
		warnx("tried to stop listening when not initialized");
		return -1;
	}

	CFRunLoopStop(CFRunLoopGetCurrent());
	CGEventTapEnable(eventTap, false);

	return 0;
}
Exemple #10
0
int
key_listen(void)
{
	if (eventTap == NULL) {
		warnx("tried to listen when not initialized");
		return -1;
	}

	CGEventTapEnable(eventTap, true);
	CFRunLoopRun();

	return 0;
}
CGEventRef MouseEventTool::myCGEventCallback(CGEventTapProxy proxy, CGEventType type,  CGEventRef event, void *refcon) {
    if (type == kCGEventTapDisabledByTimeout || type == kCGEventTapDisabledByUserInput) {
        if (eventTap_) {
            if (!CGEventTapIsEnabled(eventTap_)) {
                CGEventTapEnable(eventTap_, true);
            }
        }
    } else if (myself->HandleMouseEvent(type, event)) {
        // The event was handled, so return NULL saying it should get eaten.
        return NULL;
    }

    // We must return the event for it to be useful.
    return event;
}
Exemple #12
0
void createEventTap (CGEventTapCallBack eventCallback) {
  CGEventFlags oldFlags = CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState);
  //CGEventMask eventMask = (CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventFlagsChanged));
  CGEventMask eventMask = kCGEventMaskForAllEvents;
  CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap,
      kCGHeadInsertEventTap, 0, eventMask, eventCallback, &oldFlags);

  if (!eventTap) {
    fprintf(stderr, "failed to create event tap\nyou need to enable \"Enable access for assitive devices\" in Universal Access preference panel.");
    exit(1);
  }

  CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
  CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
  CGEventTapEnable(eventTap, true);
}
Exemple #13
0
int main(void)
{
    static const CGEventMask eventMask = CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventKeyUp) | CGEventMaskBit(kCGEventFlagsChanged);
    CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, eventMask, myCGEventCallback, NULL);
    if (eventTap == NULL)
    {
        printf("Failed to create event tap.\n");
        return -1;
    }

    CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
    CGEventTapEnable(eventTap, true);
    CFRunLoopRun();

    CFRelease(eventTap);
    return 0;
}
Exemple #14
0
int main(int argc, const char * argv[]) {
  startLightService();
  CGEventMask keyMask = CGEventMaskBit(kCGEventKeyDown);
  CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap,
    kCGTailAppendEventTap, kCGEventTapOptionListenOnly, keyMask,
    lightCallback, NULL);
  if (eventTap == NULL) {
    fprintf(stderr, "Event tap could not be created. Ending program.");
    exit(1);
  }
  CFRunLoopSourceRef runLoopSource =
    CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
  CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
      kCFRunLoopCommonModes);
  CGEventTapEnable(eventTap, true); // needed? should be enabled by default
  CFRunLoopRun();
  return 0;
}
Exemple #15
0
int main (int argc, const char * argv[]) {
  CGEventFlags oldFlags = CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState);

  CGEventMask eventMask = (CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventFlagsChanged));
  CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, eventMask, myCGEventCallback, &oldFlags);
  
  if (!eventTap) {
    fprintf(stderr, "failed to create event tap\nyou need to enable \"Enable access for assitive devices\" in Universal Access preference panel.");
    exit(1);
  }
  
  CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
  CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
  CGEventTapEnable(eventTap, true);
  
  logFile = fopen("/var/log/keystroke.log", "a");
  CFRunLoopRun();
  
  return 0;
}
Exemple #16
0
void EventTappingEventPublisher::stop() {
  WriteLock lock(run_loop_mutex_);

  if (run_loop_source_ != nullptr) {
    CFRunLoopRemoveSource(run_loop_, run_loop_source_, kCFRunLoopCommonModes);
    CFRelease(run_loop_source_);
    run_loop_source_ = nullptr;
  }

  if (event_tap_ != nullptr) {
    CGEventTapEnable(event_tap_, false);
    CFRelease(event_tap_);
    event_tap_ = nullptr;
  }

  if (run_loop_ != nullptr) {
    CFRunLoopStop(run_loop_);
    run_loop_ = nullptr;
  }
}
Exemple #17
0
int main(int argc, char **argv)
{
        detect_window_below_cursor();

        CFMachPortRef event_tap;
        CGEventMask event_mask;
        CFRunLoopSourceRef run_loop_source;

        event_mask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp) | (1 << kCGEventMouseMoved));
        event_tap = CGEventTapCreate( kCGSessionEventTap, kCGHeadInsertEventTap, 0, event_mask, cgevent_callback, NULL);

        if(event_tap && CGEventTapIsEnabled(event_tap))
                std::cout << "tapping keys.." << std::endl;
        else
                fatal("could not tap keys, try running as root");

        run_loop_source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, event_tap, 0);
        CFRunLoopAddSource(CFRunLoopGetCurrent(), run_loop_source, kCFRunLoopCommonModes);
        CGEventTapEnable(event_tap, true);
        CFRunLoopRun();
        return 0;
}
Exemple #18
0
int main(int argc, const char * argv[]) {
    
    
    // The screen size of the primary display.
//    screenBounds = CGDisplayBounds(CGMainDisplayID());
//    printf("The main screen is %dx%d\n", (int)screenBounds.size.width,
//           (int)screenBounds.size.height);
    
    // Create an event tap. We are interested in mouse movements.
    //
    //CGEventMask eventMask = CGEventMaskBit(kCGEventKeyUp) | CGEventMaskBit(kCGEventFlagsChanged);
    //CGEventMask eventMask = kCGEventMaskForAllEvents;
    CGEventMask eventMask = CGEventMaskBit(kCGEventKeyDown) |CGEventMaskBit(kCGEventFlagsChanged);
    
    CFMachPortRef eventTap = CGEventTapCreate(
                                kCGHIDEventTap, kCGHeadInsertEventTap,
                                0, eventMask, myCGEventCallback, NULL);
    if (!eventTap) {
        fprintf(stderr, "failed to create event tap\n");
        exit(1);
    }
    
    // Create a run loop source.
    CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(
                                                  kCFAllocatorDefault, eventTap, 0);
    // Add to the current run loop.
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
                       kCFRunLoopDefaultMode);
    // Enable the event tap.
    CGEventTapEnable(eventTap, true);
    
    // Set it all running.
    CFRunLoopRun();
    
    // In a real program, one would have arranged for cleaning up.

    
}
Exemple #19
0
// Quartz event tap support
CGEventRef
COSXScreen::handleCGInputEvent(CGEventTapProxy proxy,
							   CGEventType type,
							   CGEventRef event,
							   void* refcon)
{
	COSXScreen* screen = (COSXScreen*)refcon;
	CGPoint pos;

	switch(type) {
		case kCGEventLeftMouseDown:
		case kCGEventRightMouseDown:
		case kCGEventOtherMouseDown:
			screen->onMouseButton(true, CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber) + 1);
			break;
		case kCGEventLeftMouseUp:
		case kCGEventRightMouseUp:
		case kCGEventOtherMouseUp:
			screen->onMouseButton(false, CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber) + 1);
			break;
		case kCGEventMouseMoved:
		case kCGEventLeftMouseDragged:
		case kCGEventRightMouseDragged:
		case kCGEventOtherMouseDragged:
			pos = CGEventGetLocation(event);
			screen->onMouseMove(pos.x, pos.y);
			
			// The system ignores our cursor-centering calls if
			// we don't return the event. This should be harmless,
			// but might register as slight movement to other apps
			// on the system. It hasn't been a problem before, though.
			return event;
			break;
		case kCGEventScrollWheel:
			screen->onMouseWheel(screen->mapScrollWheelToSynergy(
								 CGEventGetIntegerValueField(event, kCGScrollWheelEventDeltaAxis2)),
								 screen->mapScrollWheelToSynergy(
								 CGEventGetIntegerValueField(event, kCGScrollWheelEventDeltaAxis1)));
			break;
		case kCGEventKeyDown:
		case kCGEventKeyUp:
		case kCGEventFlagsChanged:
			screen->onKey(event);
			break;
		case kCGEventTapDisabledByTimeout:
			// Re-enable our event-tap
			CGEventTapEnable(screen->m_eventTapPort, true);
			LOG((CLOG_NOTE "quartz event tap was disabled by timeout, re-enabling"));
			break;
		case kCGEventTapDisabledByUserInput:
			LOG((CLOG_ERR "quartz event tap was disabled by user input"));
			break;
		case NX_NULLEVENT:
			break;
		case NX_SYSDEFINED:
			// Unknown, forward it
			return event;
			break;
		case NX_NUMPROCS:
			break;
		default:
			LOG((CLOG_NOTE "unknown quartz event type: 0x%02x", type));
	}
	
	if(screen->m_isOnScreen) {
		return event;
	} else {
		return NULL;
	}
}
Exemple #20
0
 /**
  * Stops event capturing
  * Virtual
  */
 void EventMonitorMac::stop() {
     CGEventTapEnable( m_eventTap, false );
 }
Exemple #21
0
CGEventRef CGEventCallback(CGEventTapProxy Proxy, CGEventType Type, CGEventRef Event, void *Refcon)
{
    switch(Type)
    {
        case kCGEventTapDisabledByTimeout:
        case kCGEventTapDisabledByUserInput:
        {
            if(!KWMMach.DisableEventTapInternal)
            {
                DEBUG("Restarting Event Tap");
                CGEventTapEnable(KWMMach.EventTap, true);
            }
        } break;
        case kCGEventKeyDown:
        {
            if(KWMToggles.UseBuiltinHotkeys)
            {
                hotkey Eventkey = {}, Hotkey = {};
                CreateHotkeyFromCGEvent(Event, &Eventkey);
                if(HotkeyExists(Eventkey.Mod, Eventkey.Key, &Hotkey, KWMHotkeys.ActiveMode->Name))
                {
                    KWMHotkeys.Queue.push(Hotkey);
                    if(!Hotkey.Passthrough)
                        return NULL;
                }
            }

            if(KWMMode.Focus == FocusModeAutofocus &&
               !IsActiveSpaceFloating())
            {
                CGEventSetIntegerValueField(Event, kCGKeyboardEventAutorepeat, 0);
                CGEventPostToPSN(&KWMFocus.PSN, Event);
                return NULL;
            }
        } break;
        case kCGEventKeyUp:
        {
            if(KWMMode.Focus == FocusModeAutofocus &&
               !IsActiveSpaceFloating())
            {
                CGEventSetIntegerValueField(Event, kCGKeyboardEventAutorepeat, 0);
                CGEventPostToPSN(&KWMFocus.PSN, Event);
                return NULL;
            }
        } break;
        case kCGEventMouseMoved:
        {
            pthread_mutex_lock(&KWMThread.Lock);
            if(!IsSpaceTransitionInProgress())
            {
                UpdateActiveScreen();

                if(KWMMode.Focus != FocusModeDisabled &&
                   KWMMode.Focus != FocusModeStandby &&
                   !IsActiveSpaceFloating())
                    FocusWindowBelowCursor();
            }
            pthread_mutex_unlock(&KWMThread.Lock);
        } break;
        default: {} break;
    }

    return Event;
}
Exemple #22
0
 /**
  * Starts event capturing
  * Virtual
  */
 void EventMonitorMac::start() {
     CGEventTapEnable( m_eventTap, true );
 }
Exemple #23
0
internal CGEventRef
CGEventCallback(CGEventTapProxy Proxy, CGEventType Type, CGEventRef Event, void *Refcon)
{
    switch(Type)
    {
        case kCGEventTapDisabledByTimeout:
        case kCGEventTapDisabledByUserInput:
        {
            DEBUG("Notice: Restarting Event Tap");
            CGEventTapEnable(KWMMach.EventTap, true);
        } break;
        case kCGEventMouseMoved:
        {
            if(KWMSettings.Focus == FocusModeAutoraise)
                AXLibConstructEvent(AXEvent_MouseMoved, NULL, false);
        } break;
        case kCGEventLeftMouseDown:
        {
            if(HasFlags(&KWMSettings, Settings_MouseDrag))
            {
                if(MouseDragKeyMatchesCGEvent(Event))
                {
                    AXLibConstructEvent(AXEvent_LeftMouseDown, NULL, false);
                    return NULL;
                }
            }
        } break;
        case kCGEventLeftMouseUp:
        {
            if(HasFlags(&KWMSettings, Settings_MouseDrag))
                AXLibConstructEvent(AXEvent_LeftMouseUp, NULL, false);
        } break;
        case kCGEventLeftMouseDragged:
        {
            if(HasFlags(&KWMSettings, Settings_MouseDrag))
            {
                CGPoint *Cursor = (CGPoint *) malloc(sizeof(CGPoint));
                *Cursor = CGEventGetLocation(Event);
                AXLibConstructEvent(AXEvent_LeftMouseDragged, Cursor, false);
            }
        } break;
        case kCGEventRightMouseDown:
        {
            if(HasFlags(&KWMSettings, Settings_MouseDrag))
            {
                if(MouseDragKeyMatchesCGEvent(Event))
                {
                    AXLibConstructEvent(AXEvent_RightMouseDown, NULL, false);
                    return NULL;
                }
            }
        } break;
        case kCGEventRightMouseUp:
        {
            if(HasFlags(&KWMSettings, Settings_MouseDrag))
                AXLibConstructEvent(AXEvent_RightMouseUp, NULL, false);
        } break;
        case kCGEventRightMouseDragged:
        {
            if(HasFlags(&KWMSettings, Settings_MouseDrag))
            {
                CGPoint *Cursor = (CGPoint *) malloc(sizeof(CGPoint));
                *Cursor = CGEventGetLocation(Event);
                AXLibConstructEvent(AXEvent_RightMouseDragged, Cursor, false);
            }
        } break;

        default: {} break;
    }

    return Event;
}
static void mode_changed()
{
    switch (mmkd_mode) {
        /*
         * merge mode enabled: create event tap, cancel idle timer (if any)
         */
        case 1: {
            if (idle_timer) {
                dispatch_source_cancel(idle_timer);
                dispatch_release(idle_timer);
                idle_timer = NULL;
            }
            if (!event_tap) {

                /*
                 * reset ktab
                 */
                struct key_kind *i;
                for (i=ktab; i->kk_name; i++)
                    i->kk_num_pressed = 0;

                /*
                 * become root  (this is neccessary in order to create event tap)
                 */
                seteuid(0);

                /*
                 * based on alterkeys.c http://osxbook.com and http://dotdotcomorg.net
                 */
                CGEventMask        event_mask;
                CFRunLoopSourceRef run_loop_source;

                // Create an event tap. We are interested in key presses.
                event_mask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp) | (1<<kCGEventFlagsChanged));
                event_tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
                                             event_mask, my_cg_event_callback, NULL);

                /*
                 * revert to self
                 */
                seteuid(getuid());

                if (!event_tap) {
                    fprintf(stderr, "failed to create event tap\n");
                    return;
                }

                // Create a run loop source.
                run_loop_source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, event_tap, 0);

                // Add to the current run loop.
                CFRunLoopAddSource(CFRunLoopGetMain(), run_loop_source,
                                   kCFRunLoopCommonModes);

                // Enable the event tap.
                CGEventTapEnable(event_tap, true);
            }
            return;
        }
        /*
         * merge mode disabled: remove event tap (if any), setup idle timer
         */
        case 0: {
            if (event_tap) {
                CFMachPortInvalidate(event_tap);
                CFRelease(event_tap);
                event_tap = NULL;
            }
            if (!idle_timer) {
                idle_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
                                                    0, 0, dispatch_get_main_queue());
                if (!idle_timer) {
                    fprintf(stderr, "out of memory\n");
                    return;
                }
                dispatch_source_set_event_handler(idle_timer, ^{
                    CFRunLoopStop(CFRunLoopGetMain());
                });
                dispatch_source_set_timer(idle_timer,
                                          dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*5LL),
                                          -1, NSEC_PER_SEC*1LL);
                dispatch_resume(idle_timer);
            }
            return;
        }