int main() {
	// Disable the logger.
	hook_set_logger_proc(&logger_proc);

	// Retrieves the keyboard auto repeat rate.
	long int repeat_rate = hook_get_auto_repeat_rate();
	if (repeat_rate >= 0) {
		fprintf(stdout,	"Auto Repeat Rate:\t%ld\n", repeat_rate);
	}
	else {
		fprintf(stderr,	"Failed to aquire keyboard auto repeat rate!\n");
	}

	// Retrieves the keyboard auto repeat delay.
	long int repeat_delay = hook_get_auto_repeat_delay();
	if (repeat_delay >= 0) {
		fprintf(stdout,	"Auto Repeat Delay:\t%ld\n", repeat_delay);
	}
	else {
		fprintf(stderr,	"Failed to acquire keyboard auto repeat delay!\n");
	}

	// Retrieves the mouse acceleration multiplier.
	long int acceleration_multiplier = hook_get_pointer_acceleration_multiplier();
	if (acceleration_multiplier >= 0) {
		fprintf(stdout,	"Mouse Acceleration Multiplier:\t%ld\n", acceleration_multiplier);
	}
	else {
		fprintf(stderr,	"Failed to acquire mouse acceleration multiplier!\n");
	}

	// Retrieves the mouse acceleration threshold.
	long int acceleration_threshold = hook_get_pointer_acceleration_threshold();
	if (acceleration_threshold >= 0) {
		fprintf(stdout,	"Mouse Acceleration Threshold:\t%ld\n", acceleration_threshold);
	}
	else {
		fprintf(stderr,	"Failed to acquire mouse acceleration threshold!\n");
	}

	// Retrieves the mouse sensitivity.
	long int sensitivity = hook_get_pointer_sensitivity();
	if (sensitivity >= 0) {
		fprintf(stdout,	"Mouse Sensitivity:\t%ld\n", sensitivity);
	}
	else {
		fprintf(stderr,	"Failed to acquire keyboard auto repeat rate!\n");
	}

	// Retrieves the double/triple click interval.
	long int click_time = hook_get_multi_click_time();
	if (click_time >= 0) {
		fprintf(stdout,	"Multi-Click Time:\t%ld\n", click_time);
	}
	else {
		fprintf(stderr,	"Failed to acquire keyboard auto repeat rate!\n");
	}

	return EXIT_SUCCESS;
}
示例#2
0
// JNI exit point, This is executed when the Java virtual machine detaches from the native library.
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
	// Grab the currently JNI interface pointer so we can cleanup the
	// system properties set on load.
	JNIEnv *env = NULL;
	if ((*jvm)->GetEnv(jvm, (void **)(&env), jni_version) == JNI_OK) {
		// Clear java properties from native sources.
		jni_ClearProperties(env);
	}
	else {
		// It is not critical that these values are cleared so no exception
		// will be thrown.
		jni_Logger(LOG_LEVEL_WARN, "%s [%u]: Failed to call jni_ClearProperties()!\n",
				__FUNCTION__, __LINE__);
	}

	jni_Logger(LOG_LEVEL_DEBUG, "%s [%u]: JNI Unloaded.\n",
			__FUNCTION__, __LINE__);

	// Unset the hook callback function to dispatch events.
	hook_set_dispatch_proc(NULL);

	// Unset Java logger for native code messages.
	hook_set_logger_proc(NULL);
	
	if (env != NULL) {
		jni_DestroyGlobals(env);
	}
}
int hook_enable() {
	// Lock the thread control mutex.  This will be unlocked when the
	// thread has finished starting, or when it has fully stopped.
	#ifdef _WIN32
	WaitForSingleObject(hook_control_mutex, INFINITE);
	#else
	pthread_mutex_lock(&hook_control_mutex);
	#endif
	
	// Set the initial status.
	int status = UIOHOOK_FAILURE;
	
	#ifndef _WIN32
	// Create the thread attribute.
	pthread_attr_t hook_thread_attr;
	pthread_attr_init(&hook_thread_attr);

	// Get the policy and priority for the thread attr.
	int policy;
	pthread_attr_getschedpolicy(&hook_thread_attr, &policy);
	int priority = sched_get_priority_max(policy);
	#endif
	
	#if defined(_WIN32)
	DWORD hook_thread_id;
	DWORD *hook_thread_status = malloc(sizeof(DWORD));
	hook_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) hook_thread_proc, hook_thread_status, 0, &hook_thread_id);
	if (hook_thread != INVALID_HANDLE_VALUE) {
	#else
	int *hook_thread_status = malloc(sizeof(int));
	if (pthread_create(&hook_thread, &hook_thread_attr, hook_thread_proc, hook_thread_status) == 0) {
	#endif
		#if defined(_WIN32)
		// Attempt to set the thread priority to time critical.
		if (SetThreadPriority(hook_thread, THREAD_PRIORITY_TIME_CRITICAL) == 0) {
			logger_proc(LOG_LEVEL_WARN, "%s [%u]: Could not set thread priority %li for thread %#p! (%#lX)\n",
					__FUNCTION__, __LINE__, (long) THREAD_PRIORITY_TIME_CRITICAL,
					hook_thread	, (unsigned long) GetLastError());
		}
		#elif (defined(__APPLE__) && defined(__MACH__)) || _POSIX_C_SOURCE >= 200112L
		// Some POSIX revisions do not support pthread_setschedprio so we will 
		// use pthread_setschedparam instead.
		struct sched_param param = { .sched_priority = priority };
		if (pthread_setschedparam(hook_thread, SCHED_OTHER, &param) != 0) {
			logger_proc(LOG_LEVEL_WARN,	"%s [%u]: Could not set thread priority %i for thread 0x%lX!\n",
					__FUNCTION__, __LINE__, priority, (unsigned long) hook_thread);
		}
		#else
		// Raise the thread priority using glibc pthread_setschedprio.
		if (pthread_setschedprio(hook_thread, priority) != 0) {
			logger_proc(LOG_LEVEL_WARN,	"%s [%u]: Could not set thread priority %i for thread 0x%lX!\n",
					__FUNCTION__, __LINE__, priority, (unsigned long) hook_thread);
		}
		#endif
		
		
		// Wait for the thread to indicate that it has passed the 
		// initialization portion by blocking until either a EVENT_HOOK_ENABLED 
		// event is received or the thread terminates.
		// NOTE This unlocks the hook_control_mutex while we wait.
		#ifdef _WIN32
		WaitForSingleObject(hook_control_cond, INFINITE);
		#else
		pthread_cond_wait(&hook_control_cond, &hook_control_mutex);
		#endif

		#ifdef _WIN32
		if (WaitForSingleObject(hook_running_mutex, 0) != WAIT_TIMEOUT) {
		#else
		if (pthread_mutex_trylock(&hook_running_mutex) == 0) {
		#endif
			// Lock Successful; The hook is not running but the hook_control_cond 
			// was signaled!  This indicates that there was a startup problem!
			
			// Get the status back from the thread.
			#ifdef _WIN32
			WaitForSingleObject(hook_thread,  INFINITE);
			GetExitCodeThread(hook_thread, hook_thread_status);
			#else
			pthread_join(hook_thread, (void **) &hook_thread_status);
			status = *hook_thread_status;
			#endif
		}
		else {
			// Lock Failure; The hook is currently running and wait was signaled
			// indicating that we have passed all possible start checks.  We can 
			// always assume a successful startup at this point.
			status = UIOHOOK_SUCCESS;
		}
		
		free(hook_thread_status);
	
		logger_proc(LOG_LEVEL_DEBUG,	"%s [%u]: Thread Result: (%#X).\n",
				__FUNCTION__, __LINE__, status);
	}
	else {
		status = UIOHOOK_ERROR_THREAD_CREATE;
	}
	
	// Make sure the control mutex is unlocked.
	#ifdef _WIN32
	ReleaseMutex(hook_control_mutex);
	#else
	pthread_mutex_unlock(&hook_control_mutex);
	#endif
	
	return status;
}


int main() {
	// Lock the thread control mutex.  This will be unlocked when the
	// thread has finished starting, or when it has fully stopped.
	#ifdef _WIN32
	// Create event handles for the thread hook.
	hook_running_mutex = CreateMutex(NULL, FALSE, TEXT("hook_running_mutex"));
	hook_control_mutex = CreateMutex(NULL, FALSE, TEXT("hook_control_mutex"));
	hook_control_cond = CreateEvent(NULL, TRUE, FALSE, TEXT("hook_control_cond"));
	#else
	pthread_mutex_init(&hook_running_mutex, NULL);
	pthread_mutex_init(&hook_control_mutex, NULL);
	pthread_cond_init(&hook_control_cond, NULL);
	#endif
	
	// Set the logger callback for library output.
	hook_set_logger_proc(&logger_proc);
	
	// Set the event callback for uiohook events.
	hook_set_dispatch_proc(&dispatch_proc);

	// Start the hook and block.
	// NOTE If EVENT_HOOK_ENABLED was delivered, the status will always succeed.
	int status = hook_enable();
	switch (status) {
		case UIOHOOK_SUCCESS:
			// We no longer block, so we need to explicitly wait for the thread to die.
			#ifdef _WIN32
			WaitForSingleObject(hook_thread,  INFINITE);
			#else
			#if defined(__APPLE__) && defined(__MACH__)
			// NOTE Darwin requires that you start your own runloop from main.
			CFRunLoopRun();
			#endif
			
			pthread_join(hook_thread, NULL);
			#endif
			break;

		// System level errors.
		case UIOHOOK_ERROR_OUT_OF_MEMORY:
			logger_proc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)\n", status);
			break;


		// X11 specific errors.
		case UIOHOOK_ERROR_X_OPEN_DISPLAY:
			logger_proc(LOG_LEVEL_ERROR, "Failed to open X11 display. (%#X)\n", status);
			break;

		case UIOHOOK_ERROR_X_RECORD_NOT_FOUND:
			logger_proc(LOG_LEVEL_ERROR, "Unable to locate XRecord extension. (%#X)\n", status);
			break;

		case UIOHOOK_ERROR_X_RECORD_ALLOC_RANGE:
			logger_proc(LOG_LEVEL_ERROR, "Unable to allocate XRecord range. (%#X)\n", status);
			break;

		case UIOHOOK_ERROR_X_RECORD_CREATE_CONTEXT:
			logger_proc(LOG_LEVEL_ERROR, "Unable to allocate XRecord context. (%#X)\n", status);
			break;

		case UIOHOOK_ERROR_X_RECORD_ENABLE_CONTEXT:
			logger_proc(LOG_LEVEL_ERROR, "Failed to enable XRecord context. (%#X)\n", status);
			break;


		// Windows specific errors.
		case UIOHOOK_ERROR_SET_WINDOWS_HOOK_EX:
			logger_proc(LOG_LEVEL_ERROR, "Failed to register low level windows hook. (%#X)\n", status);
			break;


		// Darwin specific errors.
		case UIOHOOK_ERROR_AXAPI_DISABLED:
			logger_proc(LOG_LEVEL_ERROR, "Failed to enable access for assistive devices. (%#X)\n", status);
			break;

		case UIOHOOK_ERROR_CREATE_EVENT_PORT:
			logger_proc(LOG_LEVEL_ERROR, "Failed to create apple event port. (%#X)\n", status);
			break;

		case UIOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE:
			logger_proc(LOG_LEVEL_ERROR, "Failed to create apple run loop source. (%#X)\n", status);
			break;

		case UIOHOOK_ERROR_GET_RUNLOOP:
			logger_proc(LOG_LEVEL_ERROR, "Failed to acquire apple run loop. (%#X)\n", status);
			break;

		case UIOHOOK_ERROR_CREATE_OBSERVER:
			logger_proc(LOG_LEVEL_ERROR, "Failed to create apple run loop observer. (%#X)\n", status);
			break;

		// Default error.
		case UIOHOOK_FAILURE:
		default:
			logger_proc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)\n", status);
			break;
	}
	
	#ifdef _WIN32
	// Create event handles for the thread hook.
	CloseHandle(hook_thread);
	CloseHandle(hook_running_mutex);
	CloseHandle(hook_control_mutex);
	CloseHandle(hook_control_cond);
	#else
	pthread_mutex_destroy(&hook_running_mutex);
	pthread_mutex_destroy(&hook_control_mutex);
	pthread_cond_destroy(&hook_control_cond); 
	#endif

	return status;
}
示例#4
0
// JNI entry point, This is executed when the Java virtual machine attaches to the native library.
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
	/* Grab the currently running virtual machine so we can attach to it in
	 * functions that are not called from java.
	 */
	jvm = vm;
	JNIEnv *env = NULL;
	if ((*jvm)->GetEnv(jvm, (void **)(&env), jni_version) == JNI_OK) {
		// Create all the global class references onload to prevent class loader
		// issues with JNLP and some IDE's.
		if (jni_CreateGlobals(env) != JNI_OK) {
			#ifndef USE_QUIET
			fprintf(stderr, "%s [%u]: CreateJNIGlobals() failed!\n", 
					__FUNCTION__, __LINE__);
			#endif

			jni_ThrowFatalError(env, "Failed to locate one or more required classes.");
		}

		#ifndef USE_QUIET
		jclass PrintStream_class = (*env)->FindClass(env, "java/io/PrintStream");
		jfieldID out_id = (*env)->GetStaticFieldID(env, java_lang_System->cls, "out", "Ljava/io/PrintStream;");

		if (PrintStream_class != NULL && out_id != NULL) {
			jmethodID println_id = (*env)->GetMethodID(env, PrintStream_class, "println", "(Ljava/lang/String;)V");
			jobject out = (*env)->GetStaticObjectField(env, PrintStream_class, out_id);

			if (println_id != NULL && out_id != NULL) {
				jstring copyright = (*env)->NewStringUTF(env, "\n"
						"JNativeHook: Global keyboard and mouse hooking for Java.\n"
						"Copyright (C) 2006-2014 Alexander Barker.  All Rights Received.\n"
						"https://github.com/kwhat/jnativehook/\n"
						"\n"
						"JNativeHook is free software: you can redistribute it and/or modify\n"
						"it under the terms of the GNU Lesser General Public License as published\n"
						"by the Free Software Foundation, either version 3 of the License, or\n"
						"(at your option) any later version.\n"
						"\n"
						"JNativeHook is distributed in the hope that it will be useful,\n"
						"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
						"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
						"GNU General Public License for more details.\n"
						"\n"
						"You should have received a copy of the GNU Lesser General Public License\n"
						"along with this program.  If not, see <http://www.gnu.org/licenses/>.\n");

				(*env)->CallVoidMethod(env, out, println_id, copyright);
			}
		}
		#endif

		// Set Java logger for native code messages.
		hook_set_logger_proc(&jni_Logger);

		// Set java properties from native sources.
		jni_SetProperties(env);

		// Set the hook callback function to dispatch events.
		hook_set_dispatch_proc(&jni_EventDispatcher);
	}
	else {
		#ifndef USE_QUIET
		fprintf(stderr, "%s [%u]: GetEnv() failed!\n",
				__FUNCTION__, __LINE__);
		#endif

		jni_ThrowFatalError(env, "Failed to acquire JNI interface pointer");
	}

	jni_Logger(LOG_LEVEL_DEBUG, "%s [%u]: JNI Loaded.\n",
			__FUNCTION__, __LINE__);

    return jni_version;
}
示例#5
0
int main() {
	// Disable the logger.
	hook_set_logger_proc(&logger_proc);

	// Retrieves an array of screen data for each available monitor.
	uint8_t count = 0;
	screen_data *screens = hook_create_screen_info(&count);
	if (screens != NULL) {
		fprintf(stdout,	"Found %d Monitors:\n", count);

		for (int i = 0; i < count; i++) {
			fprintf(stdout,	"\tNumber:\t\t%d\n", screens[i].number);
			fprintf(stdout,	"\tOffset X:\t%d\n", screens[i].x);
			fprintf(stdout,	"\tOffset Y:\t%d\n", screens[i].y);
			fprintf(stdout,	"\tWidth:\t\t%d\n", screens[i].width);
			fprintf(stdout,	"\tHeight:\t\t%d\n", screens[i].height);
			fprintf(stdout,	"\n");
		}

		// You are responsible for freeing the memory returned by hook_create_screen_info.
		free(screens);
	}
	else {
		fprintf(stderr,	"Failed to aquire screen information!\n");
	}

	// Retrieves the keyboard auto repeat rate.
	long int repeat_rate = hook_get_auto_repeat_rate();
	if (repeat_rate >= 0) {
		fprintf(stdout,	"Auto Repeat Rate:\t%ld\n", repeat_rate);
	}
	else {
		fprintf(stderr,	"Failed to aquire keyboard auto repeat rate!\n");
	}

	// Retrieves the keyboard auto repeat delay.
	long int repeat_delay = hook_get_auto_repeat_delay();
	if (repeat_delay >= 0) {
		fprintf(stdout,	"Auto Repeat Delay:\t%ld\n", repeat_delay);
	}
	else {
		fprintf(stderr,	"Failed to aquire keyboard auto repeat delay!\n");
	}

	// Retrieves the mouse acceleration multiplier.
	long int acceleration_multiplier = hook_get_pointer_acceleration_multiplier();
	if (acceleration_multiplier >= 0) {
		fprintf(stdout,	"Mouse Acceleration Multiplier:\t%ld\n", acceleration_multiplier);
	}
	else {
		fprintf(stderr,	"Failed to aquire mouse acceleration multiplier!\n");
	}

	// Retrieves the mouse acceleration threshold.
	long int acceleration_threshold = hook_get_pointer_acceleration_threshold();
	if (acceleration_threshold >= 0) {
		fprintf(stdout,	"Mouse Acceleration Threshold:\t%ld\n", acceleration_threshold);
	}
	else {
		fprintf(stderr,	"Failed to aquire mouse acceleration threshold!\n");
	}

	// Retrieves the mouse sensitivity.
	long int sensitivity = hook_get_pointer_sensitivity();
	if (sensitivity >= 0) {
		fprintf(stdout,	"Mouse Sensitivity:\t%ld\n", sensitivity);
	}
	else {
		fprintf(stderr,	"Failed to aquire keyboard auto repeat rate!\n");
	}

	// Retrieves the double/triple click interval.
	long int click_time = hook_get_multi_click_time();
	if (click_time >= 0) {
		fprintf(stdout,	"Multi-Click Time:\t%ld\n", click_time);
	}
	else {
		fprintf(stderr,	"Failed to aquire keyboard auto repeat rate!\n");
	}

	return EXIT_SUCCESS;
}