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; }
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 ); }