示例#1
0
struct input_data *Sys_Input_Init()
{
	struct input_data *input;

	input = (struct input_data*)malloc(sizeof(struct input_data));
	if (input)
	{
		memset(input, 0, sizeof(struct input_data));

		input->ignore_mouse = 1;
		input->key_repeat_initial_delay = 500000;
		input->key_repeat_delay = 100000;
		
		NXEventHandle handle = NXOpenEventStatus();
		if (handle)
		{
			input->key_repeat_initial_delay = NXKeyRepeatThreshold(handle) * 1000000; 
			input->key_repeat_delay = NXKeyRepeatInterval(handle) * 1000000;
			
			NXCloseEventStatus(handle);
		}

		if (pthread_mutex_init(&input->mouse_mutex, 0) == 0)
		{
			if (pthread_mutex_init(&input->key_mutex, 0) == 0)
			{
				if (pthread_mutex_init(&input->thread_mutex, 0) == 0)
				{
					if (pthread_cond_init(&input->thread_has_spawned, 0) == 0)
					{
						pthread_mutex_lock(&input->thread_mutex);

						if (pthread_create(&input->thread, 0, Sys_Input_Thread, input) == 0)
						{
							pthread_cond_wait(&input->thread_has_spawned, &input->thread_mutex);
							pthread_mutex_unlock(&input->thread_mutex);

							return input;
						}

						pthread_mutex_unlock(&input->thread_mutex);
						pthread_cond_destroy(&input->thread_has_spawned);
					}

					pthread_mutex_destroy(&input->thread_mutex);
				}

				pthread_mutex_destroy(&input->key_mutex);
			}

			pthread_mutex_destroy(&input->mouse_mutex);
		}

		free(input);
	}

	return NULL;
}
示例#2
0
void
COSXScreen::fakeMouseButton(ButtonID id, bool press)
{
	NXEventHandle handle = NXOpenEventStatus();
	double clickTime = NXClickTime(handle);
	
	if ((ARCH->time() - m_lastDoubleClick) <= clickTime) {
		// drop all down and up fakes immedately after a double click.
		// TODO: perhaps there is a better way to do this, usually in
		// finder, if you tripple click a folder, it will open it and
		// then select a folder under the cursor -- and perhaps other
		// strange behaviour might happen?
		LOG((CLOG_DEBUG1 "dropping mouse button %s",
			press ? "press" : "release"));
		return;
	}
	
	// Buttons are indexed from one, but the button down array is indexed from zero
	UInt32 index = id - kButtonLeft;
	if (index >= NumButtonIDs) {
		return;
	}
	
	CGPoint pos;
	if (!m_cursorPosValid) {
		SInt32 x, y;
		getCursorPos(x, y);
	}
	pos.x = m_xCursor;
	pos.y = m_yCursor;

	// variable used to detect mouse coordinate differences between
	// old & new mouse clicks. Used in double click detection.
	SInt32 xDiff = m_xCursor - m_lastSingleClickXCursor;
	SInt32 yDiff = m_yCursor - m_lastSingleClickYCursor;
	double diff = sqrt(xDiff * xDiff + yDiff * yDiff);
	// max sqrt(x^2 + y^2) difference allowed to double click
	// since we don't have double click distance in NX APIs
	// we define our own defaults.
	const double maxDiff = sqrt(2) + 0.0001;

	if (press && (id == kButtonLeft) &&
		((ARCH->time() - m_lastSingleClick) <= clickTime) &&
		diff <= maxDiff) {

		LOG((CLOG_DEBUG1 "faking mouse left double click"));
		
		// finder does not seem to detect double clicks from two separate
		// CGEventCreateMouseEvent calls. so, if we detect a double click we
		// use CGEventSetIntegerValueField to tell the OS.
		// 
		// the caveat here is that findor will see this as a single click 
		// followed by a double click (even though there should be only a
		// double click). this may cause weird behaviour in other apps.
		//
		// for some reason using the old CGPostMouseEvent function, doesn't
		// cause double clicks (though i'm sure it did work at some point).
		
		CGEventRef event = CGEventCreateMouseEvent(
			NULL, kCGEventLeftMouseDown, pos, kCGMouseButtonLeft);
		
		CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2);
		m_buttonState.set(index, kMouseButtonDown);
		CGEventPost(kCGHIDEventTap, event);
		
		CGEventSetType(event, kCGEventLeftMouseUp);
		m_buttonState.set(index, kMouseButtonUp);
		CGEventPost(kCGHIDEventTap, event);
		
		CFRelease(event);
	
		m_lastDoubleClick = ARCH->time();
	}
	else {
		
		// ... otherwise, perform a single press or release as normal.
		
		MouseButtonState state = press ? kMouseButtonDown : kMouseButtonUp;
		
		LOG((CLOG_DEBUG1 "faking mouse button %s", press ? "press" : "release"));
		
		MouseButtonEventMapType thisButtonMap = MouseButtonEventMap[index];
		CGEventType type = thisButtonMap[state];
		
		CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, index);
	
		m_buttonState.set(index, state);
		CGEventPost(kCGHIDEventTap, event);
		
		CFRelease(event);
	
		m_lastSingleClick = ARCH->time();
		m_lastSingleClickXCursor = m_xCursor;
		m_lastSingleClickYCursor = m_yCursor;
	}
}
int
main(int argc, char **argv)
{
	NXEventHandle		hdl;
        NXEventSystemDevice	info[ 20 ];
	unsigned int		size;
	double			dbl1, dbl2;
	int			i, j;
	NXKeyMapping		mapping;
	int			mapSize;
	char *			map;
	unsigned int *		pmap;
	NXMouseScaling		scaling;

	hdl = NXOpenEventStatus();
	assert( hdl );

	size = sizeof( info) / sizeof( int);
	assert( NXEventSystemInfo(hdl, NX_EVS_DEVICE_INFO, info, &size ));
	size = size * sizeof( int) / sizeof( info[0]);
	printf("%d devices\n", size);
	for( i = 0; i < size; i++) {
		printf("%d : dev_type = %d, interface = %d, "
			"id = %d, interface_addr = %d\n", i,
		info[ i ].dev_type, info[ i ].interface,
		info[ i ].id, info[ i ].interface_addr );
	}

	dbl1 = NXKeyRepeatInterval(hdl);
	printf("NXKeyRepeatInterval = %f\n", dbl1);
	NXSetKeyRepeatInterval( hdl, 1.0 / 4 );
	dbl2 = NXKeyRepeatInterval(hdl);
	printf("now NXKeyRepeatInterval = %f\n", dbl2);

	dbl1 = NXKeyRepeatThreshold(hdl);
	printf("NXKeyRepeatThreshold = %f\n", dbl1);
	NXSetKeyRepeatThreshold( hdl, 1.0 );
	dbl2 = NXKeyRepeatThreshold(hdl);
	printf("now NXKeyRepeatThreshold = %f\n", dbl2);

	assert( KERN_SUCCESS == IOHIDGetMouseAcceleration(hdl, &dbl1));
	printf("IOHIDGetMouseAcceleration = %f\n", dbl1);

	assert( KERN_SUCCESS == IOHIDSetMouseAcceleration(hdl, 1.0));
	assert( KERN_SUCCESS == IOHIDGetMouseAcceleration(hdl, &dbl1));
	printf("now IOHIDGetMouseAcceleration = %f\n", dbl1);

	NXGetMouseScaling(hdl, &scaling);
	printf("Scaling[ %d ]: ", scaling.numScaleLevels);
	for( i = 0; i < scaling.numScaleLevels; i++)
	    printf("(%d,%d), ",
		scaling.scaleThresholds[i], scaling.scaleFactors[i]);
	printf("\n");
	assert( KERN_SUCCESS == IOHIDSetMouseAcceleration(hdl, 0.3));
	NXSetMouseScaling(hdl, &scaling);
	printf("Scaling[ %d ]: ", scaling.numScaleLevels);
	for( i = 0; i < scaling.numScaleLevels; i++)
	    printf("(%d,%d), ",
		scaling.scaleThresholds[i], scaling.scaleFactors[i]);
	printf("\n");
	assert( KERN_SUCCESS == IOHIDGetMouseAcceleration(hdl, &dbl1));
	printf("now IOHIDGetMouseAcceleration = %f\n", dbl1);


	printf("NXKeyRepeatThreshold = %f\n", dbl1);

	printf("NXAutoDimThreshold = %f\n", NXAutoDimThreshold(hdl));
	printf("NXAutoDimTime = %f\n", NXAutoDimTime(hdl));
	printf("NXIdleTime = %f\n", NXIdleTime(hdl));
	printf("NXAutoDimState = %d\n", NXAutoDimState(hdl));
	printf("NXAutoDimBrightness = %f\n", NXAutoDimBrightness(hdl));
	printf("NXScreenBrightness = %f\n", NXScreenBrightness(hdl));

	NXSetAutoDimThreshold( hdl, 200.0 );
//        NXSetAutoDimState( hdl, 1 );
        NXSetAutoDimBrightness( hdl, 0.5 );
        NXSetScreenBrightness( hdl, 0.7 );

	printf("now NXAutoDimThreshold = %f\n", NXAutoDimThreshold(hdl));
	printf("NXAutoDimTime = %f\n", NXAutoDimTime(hdl));
	printf("NXIdleTime = %f\n", NXIdleTime(hdl));
	printf("NXAutoDimState = %d\n", NXAutoDimState(hdl));
	printf("NXAutoDimBrightness = %f\n", NXAutoDimBrightness(hdl));
	printf("NXScreenBrightness = %f\n", NXScreenBrightness(hdl));

	mapSize = NXKeyMappingLength(hdl);
	map = (char *) malloc( mapSize );
	mapping.mapping = map;
	mapping.size = mapSize;
	assert( &mapping == NXGetKeyMapping(hdl, &mapping));

	pmap = (unsigned int *) map;
if(0)	while ((((char *)pmap) - map) < mapSize) {
	    printf("%04x: ", ((char *)pmap) - map);
	    for( j = 0; j < 8; j++ ) {
		printf("%08x ", *pmap++);
		if( (((char *)pmap) - map) >= mapSize)
		    break;
	    }
	    printf("\n");
	}

	map[ 0x32 ] = 0x62;	// a == b
	assert( &mapping == NXSetKeyMapping(hdl, &mapping));

	printf("sleeping...\n");
	thread_switch( 0, SWITCH_OPTION_WAIT, 10 * 1000 );

	NXResetKeyboard(hdl);
	NXResetMouse(hdl);

	return( 0 );
}