1/* 2 * Copyright (c) 1998-2009 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved. 25 * 26 * HISTORY 27 * 28 */ 29 30#include <unistd.h> 31#include <sys/types.h> 32#include <CoreFoundation/CoreFoundation.h> 33#include <libkern/OSByteOrder.h> 34#include <bootstrap_priv.h> 35#include <mach/mach.h> 36 37 38#include <IOKit/IOKitLib.h> 39#include <IOKit/hidsystem/IOHIDLib.h> 40#include <IOKit/hid/IOHIDLibPrivate.h> 41#include <IOKit/pwr_mgt/IOPMLibPrivate.h> 42#include <servers/bootstrap.h> 43#include "powermanagement.h" 44 45#if !TARGET_OS_IPHONE 46kern_return_t IOFramebufferServerStart( void ); 47#endif 48 49kern_return_t 50IOHIDCreateSharedMemory( io_connect_t connect, 51 unsigned int version ) 52{ 53#if !TARGET_OS_IPHONE 54 IOFramebufferServerStart(); 55#endif 56 uint64_t inData = version; 57 return IOConnectCallMethod( connect, 0, // Index 58 &inData, 1, NULL, 0, // Input 59 NULL, NULL, NULL, NULL); // Output 60} 61 62kern_return_t 63IOHIDSetEventsEnable( io_connect_t connect, 64 boolean_t enable ) 65{ 66 uint64_t inData = enable; 67 return IOConnectCallMethod( connect, 1, // Index 68 &inData, 1, NULL, 0, // Input 69 NULL, NULL, NULL, NULL); // Output 70} 71 72kern_return_t 73IOHIDSetCursorEnable( io_connect_t connect, 74 boolean_t enable ) 75{ 76 uint64_t inData = enable; 77 return IOConnectCallMethod( connect, 2, // Index 78 &inData, 1, NULL, 0, // Input 79 NULL, NULL, NULL, NULL); // Output 80} 81 82/* DEPRECATED form of IOHIDPostEvent(). 83kern_return_t 84IOHIDPostEvent( mach_port_t connect, 85 int type, IOGPoint location, NXEventData *data, 86 boolean_t setCursor, int flags, boolean_t setFlags) 87*/ 88 89static bool _IOPMReportSoftwareHIDEvent(UInt32 eventType) 90{ 91 mach_port_t newConnection; 92 kern_return_t kern_result = KERN_SUCCESS; 93 int allowEvent = true; 94 95 kern_result = bootstrap_look_up2(bootstrap_port, 96 kIOPMServerBootstrapName, 97 &newConnection, 98 0, 99 BOOTSTRAP_PRIVILEGED_SERVER); 100 if(KERN_SUCCESS == kern_result) { 101 io_pm_hid_event_report_activity(newConnection, eventType, &allowEvent); 102 mach_port_deallocate(mach_task_self(), newConnection); 103 } 104 return allowEvent; 105} 106 107kern_return_t 108IOHIDPostEvent( io_connect_t connect, 109 UInt32 eventType, 110 IOGPoint location, 111 const NXEventData * eventData, 112 UInt32 eventDataVersion, 113 IOOptionBits eventFlags, 114 IOOptionBits options ) 115{ 116 int * eventPid = 0; 117 size_t dataSize = sizeof(struct evioLLEvent) + sizeof(int); 118 char data[dataSize]; 119 struct evioLLEvent* event; 120 UInt32 eventDataSize = sizeof(NXEventData); 121 int allowEvent = true; 122 123 bzero(data, dataSize); 124 125 event = (struct evioLLEvent*)data; 126 127 event->type = eventType; 128 event->location = location; 129 event->flags = eventFlags; 130 event->setFlags = options; 131 event->setCursor = options & (kIOHIDSetCursorPosition | kIOHIDSetRelativeCursorPosition); 132 133 eventPid = (int *)(event + 1); 134 *eventPid = getpid(); 135 136 if ( eventDataVersion < 2 ) 137 { 138 // Support calls from legacy IOHIDPostEvent clients. 139 // 1. NXEventData was 32 bytes long. 140 // 2. eventDataVersion was (boolean_t) setCursor 141 eventDataSize = 32; 142 event->setCursor = eventDataVersion; // 0 or 1 143 } 144 145 if ( eventDataSize < sizeof(event->data) ) 146 { 147 bcopy( eventData, &(event->data), eventDataSize ); 148 bzero( ((UInt8 *)(&(event->data))) + eventDataSize, 149 sizeof(event->data) - eventDataSize ); 150 } 151 else 152 bcopy( eventData, &event->data, sizeof(event->data) ); 153 154 155 // Let PM log the software HID events 156 // also checks if NULL events are allowed in the current system state 157 allowEvent = _IOPMReportSoftwareHIDEvent(event->type); 158 159 if (allowEvent) { 160 return IOConnectCallMethod(connect, 3, // Index 161 NULL, 0, data, dataSize, // Input 162 NULL, NULL, NULL, NULL); // Output 163 } 164 else { 165 return KERN_SUCCESS; 166 } 167} 168 169extern kern_return_t 170IOHIDSetCursorBounds( io_connect_t connect, const IOGBounds * bounds ) 171{ 172 if ( !bounds ) 173 return kIOReturnBadArgument; 174 175 return IOConnectCallMethod(connect, 6, // Index 176 NULL, 0, bounds, sizeof(*bounds), // Input, 177 NULL, NULL, NULL, NULL); // Output 178} 179 180kern_return_t 181IOHIDSetMouseLocation( io_connect_t connect, int x, int y ) 182{ 183 return IOHIDSetFixedMouseLocation(connect, x << 8, y << 8); 184} 185 186kern_return_t 187IOHIDSetFixedMouseLocation( io_connect_t connect, int32_t x, int32_t y ) 188{ 189 int32_t data[3] = {x, y, 0}; 190 191 data[2] = getpid(); 192 193 return IOConnectCallMethod(connect, 4, // Index 194 NULL, 0, data, sizeof(data), // Input 195 NULL, NULL, NULL, NULL); // Output 196} 197 198kern_return_t 199IOHIDGetButtonEventNum( io_connect_t connect, 200 NXMouseButton button, int * eventNum ) 201{ 202 kern_return_t err; 203 204 uint64_t inData = button; 205 uint64_t outData; 206 uint32_t outSize = 1; 207 err = IOConnectCallMethod(connect, 5, // Index 208 &inData, 1, NULL, 0, // Input 209 &outData, &outSize, NULL, NULL); // Output 210 *eventNum = (int) outData; 211 return( err); 212} 213 214kern_return_t 215IOHIDGetStateForSelector( io_connect_t handle, int selector, UInt32 *state ) 216{ 217 kern_return_t err; 218 uint64_t inData[1] = {selector}; 219 uint64_t outData[1] = {0}; 220 uint32_t outCount = 1; 221 err = IOConnectCallMethod(handle, 5, // Index 222 inData, 1, NULL, 0, // Input 223 outData, &outCount, NULL, NULL); // Output 224 225 *state = outData[0]; 226 return err; 227} 228 229kern_return_t 230IOHIDSetStateForSelector( io_connect_t handle, int selector, UInt32 state ) 231{ 232 kern_return_t err; 233 uint64_t inData[2] = {selector, state}; 234 uint32_t outCount = 0; 235 236 err = IOConnectCallMethod(handle, 6, // Index 237 inData, 2, NULL, 0, // Input 238 NULL, &outCount, NULL, NULL); // Output 239 240 return err; 241} 242 243kern_return_t 244IOHIDGetModifierLockState( io_connect_t handle, int selector, bool *state ) 245{ 246 UInt32 internalState = 0; 247 kern_return_t err = IOHIDGetStateForSelector(handle, selector, &internalState); 248 *state = internalState ? true : false; 249 return err; 250} 251 252kern_return_t 253IOHIDSetModifierLockState( io_connect_t handle, int selector, bool state ) 254{ 255 return IOHIDSetStateForSelector(handle, selector, state); 256} 257 258kern_return_t 259IOHIDRegisterVirtualDisplay( io_connect_t handle, UInt32 *display_token ) 260{ 261 kern_return_t err; 262 uint64_t outData[1] = {0}; 263 uint32_t outCount = 1; 264 265 err = IOConnectCallMethod(handle, 7, // Index 266 NULL, 0, NULL, 0, // Input 267 outData, &outCount, NULL, NULL); // Output 268 *display_token = outData[0]; 269 return err; 270} 271 272kern_return_t 273IOHIDUnregisterVirtualDisplay( io_connect_t handle, UInt32 display_token ) 274{ 275 kern_return_t err; 276 uint64_t inData[1] = {display_token}; 277 uint32_t outCount = 0; 278 279 err = IOConnectCallMethod(handle, 8, // Index 280 inData, 1, NULL, 0, // Input 281 NULL, &outCount, NULL, NULL); // Output 282 283 return err; 284} 285 286kern_return_t 287IOHIDSetVirtualDisplayBounds( io_connect_t handle, UInt32 display_token, const IOGBounds * bounds ) 288{ 289 kern_return_t err; 290 uint64_t inData[5] = {display_token, bounds->minx, bounds->maxx, bounds->miny, bounds->maxy}; 291 uint32_t outCount = 0; 292 293 err = IOConnectCallMethod(handle, 9, // Index 294 inData, 5, NULL, 0, // Input 295 NULL, &outCount, NULL, NULL); // Output 296 297 return err; 298} 299 300kern_return_t 301IOHIDGetActivityState( io_connect_t handle, bool *hidActivityIdle ) 302{ 303 kern_return_t err; 304 uint64_t outData[1] = {0}; 305 uint32_t outCount = 1; 306 307 if (!hidActivityIdle) return kIOReturnBadArgument; 308 309 err = IOConnectCallMethod(handle, 10, // Index 310 NULL, 0, NULL, 0, // Input 311 outData, &outCount, NULL, NULL); // Output 312 *hidActivityIdle = outData[0] ? true : false; 313 return err; 314 315} 316