/* * Copyright (c) 1991 NeXT Computer, Inc. * Copyright (c) 1996-2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /****************************************************************************** event_status_driver_api.c API for the events status driver. This file implements public API. mpaque 11Oct91 Modified: 29 June 1992 Mike Paquette at NeXT Implemented API for the new Mach based Event Driver. ******************************************************************************/ #include #include #include #include #include #include #include #include /* Definitions specific to the Mach based event driver */ #define BRIGHT_MAX 64 static void secs_to_packed_nsecs(double secs, unsigned int *nsecs) { *((UInt64 *)nsecs) = (1000.0 * 1000.0 * 1000.0 * secs); } static double packed_nsecs_to_secs(unsigned int *nsecs) { return( ((double)*((UInt64 *)nsecs)) / 1000.0 / 1000.0 / 1000.0); } /* Open and Close */ NXEventHandle NXOpenEventStatus(void) { NXEventHandle handle = MACH_PORT_NULL; register kern_return_t kr; io_service_t service = MACH_PORT_NULL; mach_port_t masterPort; do { kr = IOMasterPort( MACH_PORT_NULL, &masterPort ); if( kr != KERN_SUCCESS) break; service = IORegistryEntryFromPath( masterPort, kIOServicePlane ":/IOResources/IOHIDSystem" ); if( !service) break; kr = IOServiceOpen( service, mach_task_self(), kIOHIDParamConnectType, &handle); IOObjectRelease( service ); } while( false ); return( handle ); } void NXCloseEventStatus(NXEventHandle handle) { IOServiceClose( handle ); } /* Status query */ NXEventSystemInfoType NXEventSystemInfo(NXEventHandle handle, char *flavor, NXEventSystemInfoType evs_info, unsigned int *evs_info_cnt) { kern_return_t kr; NXEventSystemDevice * info = (NXEventSystemDevice *) evs_info; int maxDeviceCount = (*evs_info_cnt) * sizeof( int) / sizeof( NXEventSystemDevice); int deviceCount = 0; io_iterator_t iter; io_registry_entry_t hidsystem; io_registry_entry_t hiddevice; CFDictionaryRef dict; CFNumberRef num; SInt32 val; // Translate the one existing old case to new format if ( ((int)flavor) == __OLD_NX_EVS_DEVICE_INFO ) flavor = NX_EVS_DEVICE_INFO; if( strcmp( flavor, NX_EVS_DEVICE_INFO)) kr = kIOReturnUnsupported; do { kr = IOConnectGetService( handle, &hidsystem ); if( KERN_SUCCESS != kr ) break; kr = IORegistryEntryGetParentIterator( hidsystem, kIOServicePlane, &iter ); IOObjectRelease( hidsystem ); if( KERN_SUCCESS != kr ) break; while( (deviceCount < maxDeviceCount) && (hiddevice = IOIteratorNext( iter ))) { kr = IORegistryEntryCreateCFProperties(hiddevice, &dict, kCFAllocatorDefault, kNilOptions); IOObjectRelease( hiddevice ); if( KERN_SUCCESS != kr ) continue; if( (num = CFDictionaryGetValue( dict, CFSTR(kIOHIDKindKey )))) { CFNumberGetValue( num, kCFNumberSInt32Type, &val ); info[ deviceCount ].dev_type = val; if( (num = CFDictionaryGetValue( dict, CFSTR(kIOHIDInterfaceIDKey )))) CFNumberGetValue( num, kCFNumberSInt32Type, &val ); else val = 0; info[ deviceCount ].interface = val; if( (num = CFDictionaryGetValue( dict, CFSTR(kIOHIDSubinterfaceIDKey )))) CFNumberGetValue( num, kCFNumberSInt32Type, &val ); else val = 0; info[ deviceCount ].id = val; info[ deviceCount ].interface_addr = 0; deviceCount++; } CFRelease(dict); } IOObjectRelease( iter ); } while( false ); if ( kr == KERN_SUCCESS ) *evs_info_cnt = (deviceCount * sizeof( NXEventSystemDevice) / sizeof( int)); else evs_info = (NXEventSystemInfoType) 0; return evs_info; } kern_return_t IOHIDSetParameter( io_connect_t handle, CFStringRef key, const void * bytes, IOByteCount size ) { kern_return_t kr = kIOReturnNoMemory; CFDataRef data; do { data = CFDataCreate( kCFAllocatorDefault, bytes, size ); if( !data) continue; kr = IOConnectSetCFProperty( handle, key, data ); CFRelease(data); } while( false ); return( kr ); } #ifndef kIOHIDParametersKey #define kIOHIDParametersKey "HIDParameters" #endif kern_return_t IOHIDGetParameter( io_connect_t handle, CFStringRef key, IOByteCount maxSize, void * bytes, IOByteCount * actualSize ) { kern_return_t kr; io_service_t hidsystem; CFDictionaryRef paramDict; CFDictionaryRef dict; CFDataRef data = NULL; int copySize; kr = IOConnectGetService( handle, &hidsystem ); if( KERN_SUCCESS != kr ) return( kr ); kr = IORegistryEntryCreateCFProperties( hidsystem, &dict, kCFAllocatorDefault, kNilOptions); IOObjectRelease( hidsystem ); if( kr != KERN_SUCCESS) return( kr ); if( (paramDict = CFDictionaryGetValue( dict, CFSTR(kIOHIDParametersKey)))) data = CFDictionaryGetValue( paramDict, key); if( !data) data = CFDictionaryGetValue( dict, key); if( data ) { copySize = CFDataGetLength(data); *actualSize = copySize; if( maxSize < copySize) copySize = maxSize; bcopy( CFDataGetBytePtr(data), bytes, copySize ); } else kr = kIOReturnBadArgument; CFRelease(dict); return( kr ); } #define NXEvSetParameterChar( h,n,p,sz ) IOHIDSetParameter( h,n,p,sz ) #define NXEvSetParameterInt( h,n,p,sz ) IOHIDSetParameter( h,n, \ (unsigned char *)p,sz * 4 ) #define NXEvGetParameterChar( h,n,mx,p,sz ) IOHIDGetParameter( h, n,mx,p,sz ) #define NXEvGetParameterInt( h,n,mx,p,sz ) IOHIDGetParameter( h,n, mx * 4, \ (unsigned char *)p,sz ); \ *sz /= 4 /* Keyboard */ void NXResetKeyboard(NXEventHandle handle) { unsigned int params[EVSIORKBD_SIZE]; NXEvSetParameterInt( handle, CFSTR(EVSIORKBD), params, EVSIORKBD_SIZE); } void NXSetKeyRepeatInterval(NXEventHandle handle, double rate) { unsigned int params[EVSIOSKR_SIZE]; secs_to_packed_nsecs( rate, params ); NXEvSetParameterInt( handle, CFSTR(EVSIOSKR), params, EVSIOSKR_SIZE); } double NXKeyRepeatInterval(NXEventHandle handle) { unsigned int params[EVSIOCKR_SIZE]; IOByteCount rcnt = EVSIOCKR_SIZE; int r; r = NXEvGetParameterInt( handle, CFSTR(EVSIOSKR), EVSIOCKR_SIZE, params, &rcnt ); if ( r != kIOReturnSuccess ) return 0.0; return packed_nsecs_to_secs( params ); } void NXSetKeyRepeatThreshold(NXEventHandle handle, double threshold) { unsigned int params[EVSIOSIKR_SIZE]; secs_to_packed_nsecs( threshold, params ); NXEvSetParameterInt( handle, CFSTR(EVSIOSIKR), params, EVSIOSIKR_SIZE); } double NXKeyRepeatThreshold(NXEventHandle handle) { unsigned int params[EVSIOCKR_SIZE]; IOByteCount rcnt = EVSIOCKR_SIZE; int r; r = NXEvGetParameterInt( handle, CFSTR(EVSIOSIKR), EVSIOCKR_SIZE, params, &rcnt ); if ( r != kIOReturnSuccess ) return 0.0; return packed_nsecs_to_secs( params ); } NXKeyMapping * NXSetKeyMapping(NXEventHandle handle, NXKeyMapping *keymap) { int r; if ( keymap->size > EVSIOSKM_SIZE ) return (NXKeyMapping *)0; r = NXEvSetParameterChar(handle, CFSTR(EVSIOSKM), (unsigned char *) keymap->mapping, keymap->size); if ( r != kIOReturnSuccess ) return (NXKeyMapping *)0; return keymap; } int NXKeyMappingLength(NXEventHandle handle) { int r; IOByteCount size; r = NXEvGetParameterChar( handle, CFSTR(EVSIOCKM), 0, (unsigned char *) 0, &size ); if ( r != kIOReturnSuccess ) size = 0; return size; } NXKeyMapping * NXGetKeyMapping(NXEventHandle handle, NXKeyMapping *keymap) { int r; r = NXEvGetParameterChar( handle, CFSTR(EVSIOCKM), keymap->size, (unsigned char *) keymap->mapping, (IOByteCount *) &keymap->size ); if ( r != kIOReturnSuccess ) return (NXKeyMapping *)0; return keymap; } /* Mouse */ void NXResetMouse(NXEventHandle handle) { unsigned int params[EVSIORMS_SIZE]; NXEvSetParameterInt(handle, CFSTR(EVSIORMS), params, EVSIORMS_SIZE); } void NXSetClickTime(NXEventHandle handle, double secs) { unsigned int params[EVSIOSCT_SIZE]; secs_to_packed_nsecs( secs, params ); NXEvSetParameterInt(handle, CFSTR(EVSIOSCT), params, EVSIOSCT_SIZE); } double NXClickTime(NXEventHandle handle) { unsigned int params[EVSIOCCT_SIZE]; IOByteCount rcnt = EVSIOCCT_SIZE; int r; r = NXEvGetParameterInt(handle, CFSTR(EVSIOCCT), EVSIOCCT_SIZE, params, &rcnt ); if ( r != kIOReturnSuccess ) return 0.0; return packed_nsecs_to_secs( params ); } void NXSetClickSpace(NXEventHandle handle, _NXSize_ *area) { unsigned int params[EVSIOSCS_SIZE]; params[EVSIOSCS_X] = (unsigned int)(area->width); params[EVSIOSCS_Y] = (unsigned int)(area->height); NXEvSetParameterInt(handle, CFSTR(EVSIOSCS), params, EVSIOSCS_SIZE); } void NXGetClickSpace(NXEventHandle handle, _NXSize_ *area) { unsigned int params[EVSIOCCS_SIZE]; IOByteCount rcnt = EVSIOCCS_SIZE; NXEvGetParameterInt(handle, CFSTR(EVSIOCCS), EVSIOCCS_SIZE, params, &rcnt ); area->width = params[EVSIOCCS_X]; area->height = params[EVSIOCCS_Y]; } void NXSetMouseScaling(NXEventHandle handle, NXMouseScaling *scaling) { double accl; accl = scaling->scaleFactors[scaling->numScaleLevels - 1] - 1.0; if( accl > 18.0) accl = 1.0; else accl /= 18.0; IOHIDSetMouseAcceleration( handle, accl ); } void NXGetMouseScaling(NXEventHandle handle, NXMouseScaling *scaling) { kern_return_t kr; double acceleration; int factor, i; const unsigned char * table; const unsigned char * nextTable; static const unsigned char nextToAccl[] = { 1, 1, 1, 5, 1, 1, 6, 2, 7, 3, 8, 5, 9, 7, 5, 2, 2, 3, 4, 4, 6, 5, 8, 6, 10, 5, 2, 2, 3, 6, 4, 10, 5, 15, 6, 22, 0 }; kr = IOHIDGetMouseAcceleration( handle, &acceleration ); if ( kr != kIOReturnSuccess ) { scaling->numScaleLevels = 0; return; } factor = (int) (18.0 * acceleration + 1.0); table = nextToAccl; do { nextTable = table + (table[0] * 2) + 1; if( factor <= nextTable[-1]) break; if( nextTable[0]) table = nextTable; else break; } while( true ); scaling->numScaleLevels = table[0]; for( i = 0; i < scaling->numScaleLevels; i++ ) { scaling->scaleThresholds[i] = table[ i * 2 + 1 ]; scaling->scaleFactors[i] = table[ i * 2 + 2 ]; } } kern_return_t IOHIDGetScrollAcceleration( io_connect_t handle, double * acceleration ) { kern_return_t kr; unsigned int fixed; IOByteCount rsize; kr = IOHIDGetParameter( handle, CFSTR(kIOHIDScrollAccelerationKey), sizeof( fixed), (unsigned char *) &fixed, &rsize ); if( kr == kIOReturnSuccess) *acceleration = ((double) fixed) / 65536.0; return( kr ); } kern_return_t IOHIDSetScrollAcceleration( io_connect_t handle, double acceleration ) { unsigned int fixed; fixed = (unsigned int) (acceleration * 65536.0); return( IOHIDSetParameter(handle, CFSTR(kIOHIDScrollAccelerationKey), (unsigned char *) &fixed, sizeof(fixed)) ); } kern_return_t IOHIDGetMouseButtonMode( io_connect_t handle, int * mode ) { IOByteCount rsize; return( IOHIDGetParameter( handle, CFSTR(kIOHIDPointerButtonMode), sizeof( *mode), (unsigned char *) mode, &rsize )); } kern_return_t IOHIDSetMouseButtonMode( io_connect_t handle, int mode ) { return( IOHIDSetParameter(handle, CFSTR(kIOHIDPointerButtonMode), (unsigned char *) &mode, sizeof(mode)) ); } kern_return_t IOHIDGetMouseAcceleration( io_connect_t handle, double * acceleration ) { kern_return_t kr; unsigned int fixed; IOByteCount rsize; kr = IOHIDGetParameter( handle, CFSTR(kIOHIDPointerAccelerationKey), sizeof( fixed), (unsigned char *) &fixed, &rsize ); if( kr == kIOReturnSuccess) *acceleration = ((double) fixed) / 65536.0; return( kr ); } kern_return_t IOHIDSetMouseAcceleration( io_connect_t handle, double acceleration ) { unsigned int fixed; fixed = (unsigned int) (acceleration * 65536.0); return( IOHIDSetParameter(handle, CFSTR(kIOHIDPointerAccelerationKey), (unsigned char *) &fixed, sizeof( fixed)) ); } kern_return_t IOHIDGetAccelerationWithKey( io_connect_t handle, CFStringRef key, double * acceleration ) { kern_return_t kr; unsigned int fixed; IOByteCount rsize; kr = IOHIDGetParameter( handle, key, sizeof( fixed), (unsigned char *) &fixed, &rsize ); if( kr == kIOReturnSuccess) *acceleration = ((double) fixed) / 65536.0; return( kr ); } kern_return_t IOHIDSetAccelerationWithKey( io_connect_t handle, CFStringRef key, double acceleration ) { unsigned int fixed; fixed = (unsigned int) (acceleration * 65536.0); return( IOHIDSetParameter(handle, key, (unsigned char *) &fixed, sizeof( fixed)) ); } /* Screen Brightness and Auto-dimming */ void NXSetAutoDimThreshold(NXEventHandle handle, double threshold) { unsigned int params[EVSIOSADT_SIZE]; secs_to_packed_nsecs( threshold, params ); NXEvSetParameterInt(handle, CFSTR(EVSIOSADT), params, EVSIOSADT_SIZE); } double NXAutoDimThreshold(NXEventHandle handle) { unsigned int params[EVSIOCADT_SIZE]; IOByteCount rcnt = EVSIOCADT_SIZE; int r; r = NXEvGetParameterInt(handle, CFSTR(EVSIOCADT), EVSIOCADT_SIZE, params, &rcnt ); if ( r != kIOReturnSuccess ) return 0.0; return packed_nsecs_to_secs( params ); } double NXAutoDimTime(NXEventHandle handle) { unsigned int params[EVSIOGDADT_SIZE]; IOByteCount rcnt = EVSIOGDADT_SIZE; int r; r = NXEvGetParameterInt( handle, CFSTR(EVSIOGDADT), EVSIOGDADT_SIZE, params, &rcnt ); if ( r != kIOReturnSuccess ) return 0.0; return packed_nsecs_to_secs( params ); } double NXIdleTime(NXEventHandle handle) { unsigned int params[EVSIOIDLE_SIZE]; IOByteCount rcnt = EVSIOIDLE_SIZE; int r; r = NXEvGetParameterInt( handle, CFSTR(EVSIOIDLE), EVSIOIDLE_SIZE, params, &rcnt ); if ( r != kIOReturnSuccess ) return 0.0; return packed_nsecs_to_secs( params ); } void NXSetAutoDimState(NXEventHandle handle, boolean_t dimmed) { unsigned int params[EVSIOSADS_SIZE]; params[0] = dimmed; NXEvSetParameterInt(handle, CFSTR(EVSIOSADS), params, EVSIOSADS_SIZE); } boolean_t NXAutoDimState(NXEventHandle handle) { unsigned int params[EVSIOCADS_SIZE]; IOByteCount rcnt = EVSIOCADS_SIZE; int r; r = NXEvGetParameterInt( handle, CFSTR(EVSIOCADS), EVSIOCADS_SIZE, params, &rcnt ); if ( r != kIOReturnSuccess ) return false; return (params[0] != 0); } void NXSetAutoDimBrightness(NXEventHandle handle, double brightness) { unsigned int params[EVSIOSADB_SIZE]; params[0] = (int) (brightness * BRIGHT_MAX); NXEvSetParameterInt(handle, CFSTR(EVSIOSADB), params, EVSIOSADB_SIZE); } double NXAutoDimBrightness(NXEventHandle handle) { unsigned int params[EVSIOSB_SIZE]; IOByteCount rcnt = EVSIOSB_SIZE; int r; r = NXEvGetParameterInt( handle, CFSTR(EVSIOSADB), EVSIOSB_SIZE, params, &rcnt ); if ( r != kIOReturnSuccess ) return 1.0; return ((double)params[0] / (double)BRIGHT_MAX); } void NXSetScreenBrightness(NXEventHandle handle, double brightness) { unsigned int params[EVSIOSB_SIZE]; params[0] = (int) (brightness * BRIGHT_MAX); NXEvSetParameterInt(handle, CFSTR(EVSIOSB), params, EVSIOSB_SIZE); } double NXScreenBrightness(NXEventHandle handle) { unsigned int params[EVSIOSB_SIZE]; IOByteCount rcnt = EVSIOSB_SIZE; int r; r = NXEvGetParameterInt( handle, CFSTR(EVSIOSB), EVSIOSB_SIZE, params, &rcnt ); if ( r != kIOReturnSuccess ) return 1.0; return ((double)params[0] / (double)BRIGHT_MAX); } /* Generic entry points */ #ifdef _undef int NXEvSetParameterInt(NXEventHandle handle, char *parameterName, unsigned int *parameterArray, unsigned int count) { return( kIOReturnUnsupported ); } int NXEvSetParameterChar(NXEventHandle handle, char *parameterName, unsigned char *parameterArray, unsigned int count) { return( kIOReturnUnsupported ); } int NXEvGetParameterInt(NXEventHandle handle, char *parameterName, unsigned int maxCount, unsigned int *parameterArray, unsigned int *returnedCount) { return( kIOReturnUnsupported ); } int NXEvGetParameterChar(NXEventHandle handle, char *parameterName, unsigned int maxCount, unsigned char *parameterArray, unsigned int *returnedCount) { return( kIOReturnUnsupported ); } #endif